diff options
34 files changed, 419 insertions, 669 deletions
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp index 0d3f6435ea..29838e455a 100644 --- a/cmds/atrace/atrace.cpp +++ b/cmds/atrace/atrace.cpp @@ -69,43 +69,44 @@ struct TracingCategory { /* Tracing categories */ static const TracingCategory k_categories[] = { - { "gfx", "Graphics", ATRACE_TAG_GRAPHICS, { } }, - { "input", "Input", ATRACE_TAG_INPUT, { } }, - { "view", "View System", ATRACE_TAG_VIEW, { } }, - { "wm", "Window Manager", ATRACE_TAG_WINDOW_MANAGER, { } }, - { "am", "Activity Manager", ATRACE_TAG_ACTIVITY_MANAGER, { } }, - { "audio", "Audio", ATRACE_TAG_AUDIO, { } }, - { "video", "Video", ATRACE_TAG_VIDEO, { } }, - { "camera", "Camera", ATRACE_TAG_CAMERA, { } }, - { "hal", "Hardware Modules", ATRACE_TAG_HAL, { } }, - { "sched", "CPU Scheduling", 0, { - { REQ, "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" }, - { REQ, "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" }, + { "gfx", "Graphics", ATRACE_TAG_GRAPHICS, { } }, + { "input", "Input", ATRACE_TAG_INPUT, { } }, + { "view", "View System", ATRACE_TAG_VIEW, { } }, + { "webview", "WebView", ATRACE_TAG_WEBVIEW, { } }, + { "wm", "Window Manager", ATRACE_TAG_WINDOW_MANAGER, { } }, + { "am", "Activity Manager", ATRACE_TAG_ACTIVITY_MANAGER, { } }, + { "audio", "Audio", ATRACE_TAG_AUDIO, { } }, + { "video", "Video", ATRACE_TAG_VIDEO, { } }, + { "camera", "Camera", ATRACE_TAG_CAMERA, { } }, + { "hal", "Hardware Modules", ATRACE_TAG_HAL, { } }, + { "sched", "CPU Scheduling", 0, { + { REQ, "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" }, + { REQ, "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" }, } }, - { "freq", "CPU Frequency", 0, { - { REQ, "/sys/kernel/debug/tracing/events/power/cpu_frequency/enable" }, - { OPT, "/sys/kernel/debug/tracing/events/power/clock_set_rate/enable" }, + { "freq", "CPU Frequency", 0, { + { REQ, "/sys/kernel/debug/tracing/events/power/cpu_frequency/enable" }, + { OPT, "/sys/kernel/debug/tracing/events/power/clock_set_rate/enable" }, } }, - { "membus", "Memory Bus Utilization", 0, { - { REQ, "/sys/kernel/debug/tracing/events/memory_bus/enable" }, + { "membus", "Memory Bus Utilization", 0, { + { REQ, "/sys/kernel/debug/tracing/events/memory_bus/enable" }, } }, - { "idle", "CPU Idle", 0, { - { REQ, "/sys/kernel/debug/tracing/events/power/cpu_idle/enable" }, + { "idle", "CPU Idle", 0, { + { REQ, "/sys/kernel/debug/tracing/events/power/cpu_idle/enable" }, } }, - { "disk", "Disk I/O", 0, { - { REQ, "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable" }, - { REQ, "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_exit/enable" }, - { REQ, "/sys/kernel/debug/tracing/events/block/block_rq_issue/enable" }, - { REQ, "/sys/kernel/debug/tracing/events/block/block_rq_complete/enable" }, + { "disk", "Disk I/O", 0, { + { REQ, "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable" }, + { REQ, "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_exit/enable" }, + { REQ, "/sys/kernel/debug/tracing/events/block/block_rq_issue/enable" }, + { REQ, "/sys/kernel/debug/tracing/events/block/block_rq_complete/enable" }, } }, - { "load", "CPU Load", 0, { - { REQ, "/sys/kernel/debug/tracing/events/cpufreq_interactive/enable" }, + { "load", "CPU Load", 0, { + { REQ, "/sys/kernel/debug/tracing/events/cpufreq_interactive/enable" }, } }, - { "sync", "Synchronization", 0, { - { REQ, "/sys/kernel/debug/tracing/events/sync/enable" }, + { "sync", "Synchronization", 0, { + { REQ, "/sys/kernel/debug/tracing/events/sync/enable" }, } }, - { "workq", "Kernel Workqueues", 0, { - { REQ, "/sys/kernel/debug/tracing/events/workqueue/enable" }, + { "workq", "Kernel Workqueues", 0, { + { REQ, "/sys/kernel/debug/tracing/events/workqueue/enable" }, } }, }; diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c index 9a1839d3ed..b3a4cc66a0 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -161,7 +161,7 @@ static void dumpstate() { if (screenshot_path[0]) { ALOGI("taking screenshot\n"); - run_command(NULL, 5, SU_PATH, "root", "screenshot", screenshot_path, NULL); + run_command(NULL, 10, "/system/bin/screencap", "-p", screenshot_path, NULL); ALOGI("wrote screenshot: %s\n", screenshot_path); } @@ -311,6 +311,7 @@ static void usage() { " -b: play sound file instead of vibrate, at beginning of job\n" " -e: play sound file instead of vibrate, at end of job\n" " -q: disable vibrate\n" + " -B: send broadcast when finished (requires -o and -p)\n" ); } @@ -323,6 +324,7 @@ int main(int argc, char *argv[]) { char* end_sound = 0; int use_socket = 0; int do_fb = 0; + int do_broadcast = 0; if (getuid() != 0) { // Old versions of the adb client would call the @@ -348,7 +350,7 @@ int main(int argc, char *argv[]) { dump_traces_path = dump_traces(); int c; - while ((c = getopt(argc, argv, "b:de:ho:svqzp")) != -1) { + while ((c = getopt(argc, argv, "b:de:ho:svqzpB")) != -1) { switch (c) { case 'b': begin_sound = optarg; break; case 'd': do_add_date = 1; break; @@ -359,6 +361,7 @@ int main(int argc, char *argv[]) { case 'q': do_vibrate = 0; break; case 'z': do_compress = 6; break; case 'p': do_fb = 1; break; + case 'B': do_broadcast = 1; break; case '?': printf("\n"); case 'h': usage(); @@ -474,6 +477,14 @@ int main(int argc, char *argv[]) { fprintf(stderr, "rename(%s, %s): %s\n", tmp_path, path, strerror(errno)); } + if (do_broadcast && use_outfile && do_fb) { + run_command(NULL, 5, "/system/bin/am", "broadcast", + "-a", "android.intent.action.BUGREPORT_FINISHED", + "--es", "android.intent.extra.BUGREPORT", path, + "--es", "android.intent.extra.SCREENSHOT", screenshot_path, + "--receiver-permission", "android.permission.DUMP", NULL); + } + ALOGI("done\n"); return 0; diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c index d081590df8..9b0013e191 100644 --- a/cmds/dumpstate/utils.c +++ b/cmds/dumpstate/utils.c @@ -379,7 +379,7 @@ pid_t redirect_to_file(FILE *redirect, char *path, int gzip_level) { chp = strchr(chp, '/'); if (chp) { *chp = 0; - mkdir(path, 0775); /* drwxrwxr-x */ + mkdir(path, 0770); /* drwxrwx--- */ *chp++ = '/'; } } diff --git a/include/android/input.h b/include/android/input.h index f2befa9ead..c8ac93866a 100644 --- a/include/android/input.h +++ b/include/android/input.h @@ -428,6 +428,7 @@ enum { enum { AINPUT_SOURCE_CLASS_MASK = 0x000000ff, + AINPUT_SOURCE_CLASS_NONE = 0x00000000, AINPUT_SOURCE_CLASS_BUTTON = 0x00000001, AINPUT_SOURCE_CLASS_POINTER = 0x00000002, AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004, @@ -446,6 +447,7 @@ enum { AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER, AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION, AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION, + AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE, AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK, AINPUT_SOURCE_ANY = 0xffffff00, diff --git a/include/gui/ISurface.h b/include/gui/ISurface.h deleted file mode 100644 index 5a928f20bc..0000000000 --- a/include/gui/ISurface.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2007 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_GUI_ISURFACE_H -#define ANDROID_GUI_ISURFACE_H - -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <utils/RefBase.h> - -#include <binder/IInterface.h> - -#include <ui/PixelFormat.h> - -namespace android { - -class IGraphicBufferProducer; - -class ISurface : public IInterface -{ -protected: - enum { - GET_SURFACE_TEXTURE = IBinder::FIRST_CALL_TRANSACTION, - }; - -public: - DECLARE_META_INTERFACE(Surface); - - virtual sp<IGraphicBufferProducer> getSurfaceTexture() const = 0; -}; - -// ---------------------------------------------------------------------------- - -class BnSurface : public BnInterface<ISurface> -{ -public: - virtual status_t onTransact( uint32_t code, - const Parcel& data, - Parcel* reply, - uint32_t flags = 0); -}; - -// ---------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_GUI_ISURFACE_H diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h index 08eddcb67f..47f955282c 100644 --- a/include/gui/ISurfaceComposer.h +++ b/include/gui/ISurfaceComposer.h @@ -103,16 +103,23 @@ public: uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ, uint32_t maxLayerZ) = 0; - /* triggers screen off and waits for it to complete */ + /* triggers screen off and waits for it to complete + * requires ACCESS_SURFACE_FLINGER permission. + */ virtual void blank(const sp<IBinder>& display) = 0; - /* triggers screen on and waits for it to complete */ + /* triggers screen on and waits for it to complete + * requires ACCESS_SURFACE_FLINGER permission. + */ virtual void unblank(const sp<IBinder>& display) = 0; /* returns information about a display * intended to be used to get information about built-in displays */ virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) = 0; + /* Capture the specified screen. requires READ_FRAME_BUFFER permission + * This function will fail if there is a secure window on screen. + */ virtual status_t captureScreen(const sp<IBinder>& display, const sp<IGraphicBufferProducer>& producer, uint32_t reqWidth, uint32_t reqHeight, diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h index 4afc86032d..cb9816fb22 100644 --- a/include/gui/ISurfaceComposerClient.h +++ b/include/gui/ISurfaceComposerClient.h @@ -27,11 +27,11 @@ #include <ui/PixelFormat.h> -#include <gui/ISurface.h> - namespace android { // ---------------------------------------------------------------------------- +class IGraphicBufferProducer; + class ISurfaceComposerClient : public IInterface { public: @@ -55,9 +55,11 @@ public: /* * Requires ACCESS_SURFACE_FLINGER permission */ - virtual sp<ISurface> createSurface( + virtual status_t createSurface( const String8& name, uint32_t w, uint32_t h, - PixelFormat format, uint32_t flags) = 0; + PixelFormat format, uint32_t flags, + sp<IBinder>* handle, + sp<IGraphicBufferProducer>* gbp) = 0; /* * Requires ACCESS_SURFACE_FLINGER permission diff --git a/include/gui/Surface.h b/include/gui/Surface.h index 18e57ed9ed..c25847ce6e 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -76,24 +76,13 @@ public: return surface != NULL && surface->getIGraphicBufferProducer() != NULL; } - /* writes the given Surface into a Parcel */ - static status_t writeToParcel(const sp<Surface>& surface, Parcel* parcel); - - /* constructs a Surface from a Parcel. see Surface::writeToParcel() - * and SurfaceControl::writeToParcel() */ - static sp<Surface> readFromParcel(const Parcel& data); - - protected: - Surface(); virtual ~Surface(); - void setIGraphicBufferProducer(const sp<IGraphicBufferProducer>& bufferProducer); private: // can't be copied Surface& operator = (const Surface& rhs); Surface(const Surface& rhs); - void init(); // ANativeWindow hooks static int hook_cancelBuffer(ANativeWindow* window, diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h index f70888ddf8..fe8eb6f197 100644 --- a/include/gui/SurfaceControl.h +++ b/include/gui/SurfaceControl.h @@ -27,7 +27,6 @@ #include <ui/PixelFormat.h> #include <ui/Region.h> -#include <gui/ISurface.h> #include <gui/ISurfaceComposerClient.h> namespace android { @@ -46,9 +45,11 @@ public: static bool isValid(const sp<SurfaceControl>& surface) { return (surface != 0) && surface->isValid(); } + bool isValid() { - return mSurface!=0 && mClient!=0; + return mHandle!=0 && mClient!=0; } + static bool isSameSurface( const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs); @@ -82,7 +83,8 @@ private: SurfaceControl( const sp<SurfaceComposerClient>& client, - const sp<ISurface>& surface); + const sp<IBinder>& handle, + const sp<IGraphicBufferProducer>& gbp); ~SurfaceControl(); @@ -90,7 +92,7 @@ private: void destroy(); sp<SurfaceComposerClient> mClient; - sp<IBinder> mSurface; + sp<IBinder> mHandle; sp<IGraphicBufferProducer> mGraphicBufferProducer; mutable Mutex mLock; mutable sp<Surface> mSurfaceData; diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h index 0798e170eb..bf4bf034ff 100644 --- a/include/private/gui/LayerState.h +++ b/include/private/gui/LayerState.h @@ -24,7 +24,6 @@ #include <ui/Region.h> #include <ui/Rect.h> -#include <gui/ISurface.h> namespace android { diff --git a/include/utils/Vector.h b/include/utils/Vector.h index f3020d63dc..ed7b725213 100644 --- a/include/utils/Vector.h +++ b/include/utils/Vector.h @@ -80,7 +80,13 @@ public: //! sets the capacity. capacity can never be reduced less than size() inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); } - /*! + /*! + * set the size of the vector. items are appended with the default + * constructor, or removed from the end as needed. + */ + inline ssize_t resize(size_t size) { return VectorImpl::resize(size); } + + /*! * C-style array access */ diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h index c4ec2ff97f..9bc50e6c2b 100644 --- a/include/utils/VectorImpl.h +++ b/include/utils/VectorImpl.h @@ -64,6 +64,7 @@ public: inline bool isEmpty() const { return mCount == 0; } size_t capacity() const; ssize_t setCapacity(size_t size); + ssize_t resize(size_t size); /*! append/insert another vector or array */ ssize_t insertVectorAt(const VectorImpl& vector, size_t index); diff --git a/libs/binder/MemoryBase.cpp b/libs/binder/MemoryBase.cpp index 033066bea3..5c823302fb 100644 --- a/libs/binder/MemoryBase.cpp +++ b/libs/binder/MemoryBase.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#define LOG_TAG "MemoryBase" #include <stdlib.h> #include <stdint.h> @@ -44,3 +45,11 @@ MemoryBase::~MemoryBase() // --------------------------------------------------------------------------- }; // namespace android + +// Backwards compatibility for libdatabase_sqlcipher (http://b/8253769). +extern "C" void _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEEij(void*, void*, ssize_t, size_t); +extern "C" void _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEElj(void* obj, void* h, long o, unsigned int size) { + _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEEij(obj, h, o, size); + ALOGW("Using temporary compatibility workaround for usage of MemoryBase " + "private API. Please fix your application!"); +} diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk index 544b66407e..5c7bb4cb48 100644 --- a/libs/gui/Android.mk +++ b/libs/gui/Android.mk @@ -17,7 +17,6 @@ LOCAL_SRC_FILES:= \ IGraphicBufferProducer.cpp \ ISensorEventConnection.cpp \ ISensorServer.cpp \ - ISurface.cpp \ ISurfaceComposer.cpp \ ISurfaceComposerClient.cpp \ LayerState.cpp \ diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index d93c067176..41ee1be927 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -995,7 +995,7 @@ void BufferQueue::freeAllBuffersExceptHeadLocked() { } status_t BufferQueue::drainQueueLocked() { - while (mSynchronousMode && !mQueue.isEmpty()) { + while (mSynchronousMode && mQueue.size() > 1) { mDequeueCondition.wait(mMutex); if (mAbandoned) { ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!"); @@ -1012,7 +1012,7 @@ status_t BufferQueue::drainQueueLocked() { status_t BufferQueue::drainQueueAndFreeBuffersLocked() { status_t err = drainQueueLocked(); if (err == NO_ERROR) { - if (mSynchronousMode) { + if (mQueue.empty()) { freeAllBuffersLocked(); } else { freeAllBuffersExceptHeadLocked(); diff --git a/libs/gui/ISurface.cpp b/libs/gui/ISurface.cpp deleted file mode 100644 index 8c25f4513d..0000000000 --- a/libs/gui/ISurface.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2007 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. - */ - -#define LOG_TAG "ISurface" - -#include <stdio.h> -#include <stdint.h> -#include <sys/types.h> - -#include <binder/Parcel.h> - -#include <gui/ISurface.h> -#include <gui/IGraphicBufferProducer.h> - -namespace android { - -// ---------------------------------------------------------------------- - -class BpSurface : public BpInterface<ISurface> -{ -public: - BpSurface(const sp<IBinder>& impl) - : BpInterface<ISurface>(impl) - { - } - - virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { - Parcel data, reply; - data.writeInterfaceToken(ISurface::getInterfaceDescriptor()); - remote()->transact(GET_SURFACE_TEXTURE, data, &reply); - return interface_cast<IGraphicBufferProducer>(reply.readStrongBinder()); - } -}; - -IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface"); - -// ---------------------------------------------------------------------- - -status_t BnSurface::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch(code) { - case GET_SURFACE_TEXTURE: { - CHECK_INTERFACE(ISurface, data, reply); - reply->writeStrongBinder( getSurfaceTexture()->asBinder() ); - return NO_ERROR; - } - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -}; // namespace android diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp index 101292d945..1adc134e40 100644 --- a/libs/gui/ISurfaceComposerClient.cpp +++ b/libs/gui/ISurfaceComposerClient.cpp @@ -29,7 +29,7 @@ #include <ui/Point.h> #include <ui/Rect.h> -#include <gui/ISurface.h> +#include <gui/IGraphicBufferProducer.h> #include <gui/ISurfaceComposerClient.h> #include <private/gui/LayerState.h> @@ -46,16 +46,13 @@ class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient> { public: BpSurfaceComposerClient(const sp<IBinder>& impl) - : BpInterface<ISurfaceComposerClient>(impl) - { + : BpInterface<ISurfaceComposerClient>(impl) { } - virtual sp<ISurface> createSurface( const String8& name, - uint32_t w, - uint32_t h, - PixelFormat format, - uint32_t flags) - { + virtual status_t createSurface(const String8& name, uint32_t w, + uint32_t h, PixelFormat format, uint32_t flags, + sp<IBinder>* handle, + sp<IGraphicBufferProducer>* gbp) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor()); data.writeString8(name); @@ -64,11 +61,12 @@ public: data.writeInt32(format); data.writeInt32(flags); remote()->transact(CREATE_SURFACE, data, &reply); - return interface_cast<ISurface>(reply.readStrongBinder()); + *handle = reply.readStrongBinder(); + *gbp = interface_cast<IGraphicBufferProducer>(reply.readStrongBinder()); + return reply.readInt32(); } - virtual status_t destroySurface(const sp<IBinder>& handle) - { + virtual status_t destroySurface(const sp<IBinder>& handle) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor()); data.writeStrongBinder(handle); @@ -92,8 +90,13 @@ status_t BnSurfaceComposerClient::onTransact( uint32_t h = data.readInt32(); PixelFormat format = data.readInt32(); uint32_t flags = data.readInt32(); - sp<ISurface> s = createSurface(name, w, h, format, flags); - reply->writeStrongBinder(s->asBinder()); + sp<IBinder> handle; + sp<IGraphicBufferProducer> gbp; + status_t result = createSurface(name, w, h, format, flags, + &handle, &gbp); + reply->writeStrongBinder(handle); + reply->writeStrongBinder(gbp->asBinder()); + reply->writeInt32(result); return NO_ERROR; } break; case DESTROY_SURFACE: { diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 950d16a4f2..ec55b57994 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -38,22 +38,8 @@ namespace android { Surface::Surface( const sp<IGraphicBufferProducer>& bufferProducer) + : mGraphicBufferProducer(bufferProducer) { - Surface::init(); - Surface::setIGraphicBufferProducer(bufferProducer); -} - -Surface::Surface() { - Surface::init(); -} - -Surface::~Surface() { - if (mConnectedToCpu) { - Surface::disconnect(NATIVE_WINDOW_API_CPU); - } -} - -void Surface::init() { // Initialize the ANativeWindow function pointers. ANativeWindow::setSwapInterval = hook_setSwapInterval; ANativeWindow::dequeueBuffer = hook_dequeueBuffer; @@ -87,10 +73,10 @@ void Surface::init() { mConnectedToCpu = false; } -void Surface::setIGraphicBufferProducer( - const sp<IGraphicBufferProducer>& bufferProducer) -{ - mGraphicBufferProducer = bufferProducer; +Surface::~Surface() { + if (mConnectedToCpu) { + Surface::disconnect(NATIVE_WINDOW_API_CPU); + } } sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const { @@ -723,23 +709,6 @@ static status_t copyBlt( // ---------------------------------------------------------------------------- -status_t Surface::writeToParcel( - const sp<Surface>& surface, Parcel* parcel) { - sp<IGraphicBufferProducer> bp; - if (surface != NULL) { - bp = surface->mGraphicBufferProducer; - } - return parcel->writeStrongBinder(bp->asBinder()); -} - -sp<Surface> Surface::readFromParcel(const Parcel& data) { - sp<IBinder> binder(data.readStrongBinder()); - sp<IGraphicBufferProducer> bp(interface_cast<IGraphicBufferProducer>(binder)); - return bp != NULL ? new Surface(bp): NULL; -} - -// ---------------------------------------------------------------------------- - status_t Surface::lock( ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds) { diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index edfa78a35f..4a4c0c8df4 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -32,7 +32,6 @@ #include <ui/DisplayInfo.h> #include <gui/IGraphicBufferProducer.h> -#include <gui/ISurface.h> #include <gui/ISurfaceComposer.h> #include <gui/ISurfaceComposerClient.h> #include <gui/SurfaceComposerClient.h> @@ -471,14 +470,18 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface( PixelFormat format, uint32_t flags) { - sp<SurfaceControl> result; + sp<SurfaceControl> sur; if (mStatus == NO_ERROR) { - sp<ISurface> surface = mClient->createSurface(name, w, h, format, flags); - if (surface != 0) { - result = new SurfaceControl(this, surface); + sp<IBinder> handle; + sp<IGraphicBufferProducer> gbp; + status_t err = mClient->createSurface(name, w, h, format, flags, + &handle, &gbp); + ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err)); + if (err == NO_ERROR) { + sur = new SurfaceControl(this, handle, gbp); } } - return result; + return sur; } sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName, diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index ef52269b0a..bb57948d50 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -34,7 +34,6 @@ #include <ui/GraphicBuffer.h> #include <ui/Rect.h> -#include <gui/ISurface.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> @@ -48,13 +47,10 @@ namespace android { SurfaceControl::SurfaceControl( const sp<SurfaceComposerClient>& client, - const sp<ISurface>& surface) - : mClient(client) + const sp<IBinder>& handle, + const sp<IGraphicBufferProducer>& gbp) + : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp) { - if (surface != 0) { - mSurface = surface->asBinder(); - mGraphicBufferProducer = surface->getSurfaceTexture(); - } } SurfaceControl::~SurfaceControl() @@ -65,12 +61,12 @@ SurfaceControl::~SurfaceControl() void SurfaceControl::destroy() { if (isValid()) { - mClient->destroySurface(mSurface); + mClient->destroySurface(mHandle); } // clear all references and trigger an IPC now, to make sure things // happen without delay, since these resources are quite heavy. mClient.clear(); - mSurface.clear(); + mHandle.clear(); mGraphicBufferProducer.clear(); IPCThreadState::self()->flushCommands(); } @@ -91,81 +87,81 @@ bool SurfaceControl::isSameSurface( { if (lhs == 0 || rhs == 0) return false; - return lhs->mSurface == rhs->mSurface; + return lhs->mHandle == rhs->mHandle; } status_t SurfaceControl::setLayerStack(int32_t layerStack) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); - return client->setLayerStack(mSurface, layerStack); + return client->setLayerStack(mHandle, layerStack); } status_t SurfaceControl::setLayer(int32_t layer) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); - return client->setLayer(mSurface, layer); + return client->setLayer(mHandle, layer); } status_t SurfaceControl::setPosition(int32_t x, int32_t y) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); - return client->setPosition(mSurface, x, y); + return client->setPosition(mHandle, x, y); } status_t SurfaceControl::setSize(uint32_t w, uint32_t h) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); - return client->setSize(mSurface, w, h); + return client->setSize(mHandle, w, h); } status_t SurfaceControl::hide() { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); - return client->hide(mSurface); + return client->hide(mHandle); } status_t SurfaceControl::show() { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); - return client->show(mSurface); + return client->show(mHandle); } status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); - return client->setFlags(mSurface, flags, mask); + return client->setFlags(mHandle, flags, mask); } status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); - return client->setTransparentRegionHint(mSurface, transparent); + return client->setTransparentRegionHint(mHandle, transparent); } status_t SurfaceControl::setAlpha(float alpha) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); - return client->setAlpha(mSurface, alpha); + return client->setAlpha(mHandle, alpha); } status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); - return client->setMatrix(mSurface, dsdx, dtdx, dsdy, dtdy); + return client->setMatrix(mHandle, dsdx, dtdx, dsdy, dtdy); } status_t SurfaceControl::setCrop(const Rect& crop) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); - return client->setCrop(mSurface, crop); + return client->setCrop(mHandle, crop); } status_t SurfaceControl::validate() const { - if (mSurface==0 || mClient==0) { - ALOGE("invalid ISurface (%p) or client (%p)", - mSurface.get(), mClient.get()); + if (mHandle==0 || mClient==0) { + ALOGE("invalid handle (%p) or client (%p)", + mHandle.get(), mClient.get()); return NO_INIT; } return NO_ERROR; diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp index 2b39bce2e8..0623f46a5b 100644 --- a/libs/utils/RefBase.cpp +++ b/libs/utils/RefBase.cpp @@ -15,6 +15,7 @@ */ #define LOG_TAG "RefBase" +#define LOG_NDEBUG 0 #include <utils/RefBase.h> @@ -440,39 +441,68 @@ bool RefBase::weakref_type::attemptIncStrong(const void* id) incWeak(id); weakref_impl* const impl = static_cast<weakref_impl*>(this); - int32_t curCount = impl->mStrong; - ALOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow", - this); + + ALOG_ASSERT(curCount >= 0, + "attemptIncStrong called on %p after underflow", this); + while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { + // we're in the easy/common case of promoting a weak-reference + // from an existing strong reference. if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) { break; } + // the strong count has changed on us, we need to re-assert our + // situation. curCount = impl->mStrong; } if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) { - bool allow; - if (curCount == INITIAL_STRONG_VALUE) { - // Attempting to acquire first strong reference... this is allowed - // if the object does NOT have a longer lifetime (meaning the - // implementation doesn't need to see this), or if the implementation - // allows it to happen. - allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK - || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); + // we're now in the harder case of either: + // - there never was a strong reference on us + // - or, all strong references have been released + if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) { + // this object has a "normal" life-time, i.e.: it gets destroyed + // when the last strong reference goes away + if (curCount <= 0) { + // the last strong-reference got released, the object cannot + // be revived. + decWeak(id); + return false; + } + + // here, curCount == INITIAL_STRONG_VALUE, which means + // there never was a strong-reference, so we can try to + // promote this object; we need to do that atomically. + while (curCount > 0) { + if (android_atomic_cmpxchg(curCount, curCount + 1, + &impl->mStrong) == 0) { + break; + } + // the strong count has changed on us, we need to re-assert our + // situation (e.g.: another thread has inc/decStrong'ed us) + curCount = impl->mStrong; + } + + if (curCount <= 0) { + // promote() failed, some other thread destroyed us in the + // meantime (i.e.: strong count reached zero). + decWeak(id); + return false; + } } else { - // Attempting to revive the object... this is allowed - // if the object DOES have a longer lifetime (so we can safely - // call the object with only a weak ref) and the implementation - // allows it to happen. - allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK - && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); - } - if (!allow) { - decWeak(id); - return false; + // this object has an "extended" life-time, i.e.: it can be + // revived from a weak-reference only. + // Ask the object's implementation if it agrees to be revived + if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) { + // it didn't so give-up. + decWeak(id); + return false; + } + // grab a strong-reference, which is always safe due to the + // extended life-time. + curCount = android_atomic_inc(&impl->mStrong); } - curCount = android_atomic_inc(&impl->mStrong); // If the strong reference count has already been incremented by // someone else, the implementor of onIncStrongAttempted() is holding @@ -490,11 +520,23 @@ bool RefBase::weakref_type::attemptIncStrong(const void* id) ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount); #endif - if (curCount == INITIAL_STRONG_VALUE) { - android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong); - impl->mBase->onFirstRef(); + // now we need to fix-up the count if it was INITIAL_STRONG_VALUE + // this must be done safely, i.e.: handle the case where several threads + // were here in attemptIncStrong(). + curCount = impl->mStrong; + while (curCount >= INITIAL_STRONG_VALUE) { + ALOG_ASSERT(curCount > INITIAL_STRONG_VALUE, + "attemptIncStrong in %p underflowed to INITIAL_STRONG_VALUE", + this); + if (android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE, + &impl->mStrong) == 0) { + break; + } + // the strong-count changed on us, we need to re-assert the situation, + // for e.g.: it's possible the fix-up happened in another thread. + curCount = impl->mStrong; } - + return true; } diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp index c3257bb3eb..70f49deee6 100644 --- a/libs/utils/VectorImpl.cpp +++ b/libs/utils/VectorImpl.cpp @@ -343,6 +343,16 @@ ssize_t VectorImpl::setCapacity(size_t new_capacity) return new_capacity; } +ssize_t VectorImpl::resize(size_t size) { + ssize_t result = NO_ERROR; + if (size > mCount) { + result = insertAt(mCount, size - mCount); + } else if (size < mCount) { + result = removeItemsAt(size, mCount - size); + } + return result < 0 ? result : size; +} + void VectorImpl::release_storage() { if (mStorage) { diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index 0575e352d1..dd65348ea0 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -105,10 +105,11 @@ status_t Client::onTransact( } -sp<ISurface> Client::createSurface( +status_t Client::createSurface( const String8& name, - uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags) + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, + sp<IBinder>* handle, + sp<IGraphicBufferProducer>* gbp) { /* * createSurface must be called from the GL thread so that it can @@ -116,9 +117,11 @@ sp<ISurface> Client::createSurface( */ class MessageCreateLayer : public MessageBase { - sp<ISurface> result; SurfaceFlinger* flinger; Client* client; + sp<IBinder>* handle; + sp<IGraphicBufferProducer>* gbp; + status_t result; const String8& name; uint32_t w, h; PixelFormat format; @@ -126,21 +129,23 @@ sp<ISurface> Client::createSurface( public: MessageCreateLayer(SurfaceFlinger* flinger, const String8& name, Client* client, - uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags) - : flinger(flinger), client(client), name(name), - w(w), h(h), format(format), flags(flags) - { + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, + sp<IBinder>* handle, + sp<IGraphicBufferProducer>* gbp) + : flinger(flinger), client(client), + handle(handle), gbp(gbp), + name(name), w(w), h(h), format(format), flags(flags) { } - sp<ISurface> getResult() const { return result; } + status_t getResult() const { return result; } virtual bool handler() { - result = flinger->createLayer(name, client, w, h, format, flags); + result = flinger->createLayer(name, client, w, h, format, flags, + handle, gbp); return true; } }; sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), - name, this, w, h, format, flags); + name, this, w, h, format, flags, handle, gbp); mFlinger->postMessageSync(msg); return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); } diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h index 4f34b86592..84e649f4f2 100644 --- a/services/surfaceflinger/Client.h +++ b/services/surfaceflinger/Client.h @@ -52,10 +52,11 @@ public: private: // ISurfaceComposerClient interface - virtual sp<ISurface> createSurface( + virtual status_t createSurface( const String8& name, - uint32_t w, uint32_t h,PixelFormat format, - uint32_t flags); + uint32_t w, uint32_t h,PixelFormat format, uint32_t flags, + sp<IBinder>* handle, + sp<IGraphicBufferProducer>* gbp); virtual status_t destroySurface(const sp<IBinder>& handle); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 44ef0b8793..1677c76876 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -52,7 +52,8 @@ namespace android { int32_t Layer::sSequence = 1; -Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client) +Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, + const String8& name, uint32_t w, uint32_t h, uint32_t flags) : contentDirty(false), sequence(uint32_t(android_atomic_inc(&sSequence))), mFlinger(flinger), @@ -79,18 +80,42 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client) { mCurrentCrop.makeInvalid(); glGenTextures(1, &mTextureName); + + uint32_t layerFlags = 0; + if (flags & ISurfaceComposerClient::eHidden) + layerFlags = layer_state_t::eLayerHidden; + + if (flags & ISurfaceComposerClient::eNonPremultiplied) + mPremultipliedAlpha = false; + + mName = name; + + mCurrentState.active.w = w; + mCurrentState.active.h = h; + mCurrentState.active.crop.makeInvalid(); + mCurrentState.z = 0; + mCurrentState.alpha = 0xFF; + mCurrentState.layerStack = 0; + mCurrentState.flags = layerFlags; + mCurrentState.sequence = 0; + mCurrentState.transform.set(0, 0); + mCurrentState.requested = mCurrentState.active; + + // drawing state & current state are identical + mDrawingState = mCurrentState; } void Layer::onFirstRef() { // Creates a custom BufferQueue for SurfaceFlingerConsumer to use - sp<BufferQueue> bq = new SurfaceTextureLayer(); + sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger); mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true, GL_TEXTURE_EXTERNAL_OES, false, bq); mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); mSurfaceFlingerConsumer->setFrameAvailableListener(this); mSurfaceFlingerConsumer->setSynchronousMode(true); + mSurfaceFlingerConsumer->setName(mName); #ifdef TARGET_DISABLE_TRIPLE_BUFFERING #warning "disabling triple buffering" @@ -103,8 +128,7 @@ void Layer::onFirstRef() updateTransformHint(hw); } -Layer::~Layer() -{ +Layer::~Layer() { sp<Client> c(mClientRef.promote()); if (c != 0) { c->detachLayer(this); @@ -129,8 +153,9 @@ void Layer::onFrameAvailable() { mFlinger->signalLayerUpdate(); } -// called with SurfaceFlinger::mStateLock as soon as the layer is entered -// in the purgatory list +// called with SurfaceFlinger::mStateLock from the drawing thread after +// the layer has been remove from the current state list (and just before +// it's removed from the drawing state list) void Layer::onRemoved() { mSurfaceFlingerConsumer->abandon(); } @@ -139,39 +164,10 @@ void Layer::onRemoved() { // set-up // --------------------------------------------------------------------------- -void Layer::setName(const String8& name) { - mName = name; - mSurfaceFlingerConsumer->setName(name); -} - String8 Layer::getName() const { return mName; } -void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags) -{ - uint32_t layerFlags = 0; - if (flags & ISurfaceComposerClient::eHidden) - layerFlags = layer_state_t::eLayerHidden; - - if (flags & ISurfaceComposerClient::eNonPremultiplied) - mPremultipliedAlpha = false; - - mCurrentState.active.w = w; - mCurrentState.active.h = h; - mCurrentState.active.crop.makeInvalid(); - mCurrentState.z = 0; - mCurrentState.alpha = 0xFF; - mCurrentState.layerStack = 0; - mCurrentState.flags = layerFlags; - mCurrentState.sequence = 0; - mCurrentState.transform.set(0, 0); - mCurrentState.requested = mCurrentState.active; - - // drawing state & current state are identical - mDrawingState = mCurrentState; -} - status_t Layer::setBuffers( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { @@ -207,59 +203,47 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, return NO_ERROR; } -sp<ISurface> Layer::createSurface() { +sp<IBinder> Layer::getHandle() { + Mutex::Autolock _l(mLock); + + LOG_ALWAYS_FATAL_IF(mHasSurface, + "Layer::getHandle() has already been called"); + + mHasSurface = true; + /* - * This class provides an implementation of BnSurface (the "native" or - * "remote" side of the Binder IPC interface ISurface), and mixes in - * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for - * this layer when the BSurface is destroyed. - * - * The idea is to provide a handle to the Layer through ISurface that - * is cleaned up automatically when the last reference to the ISurface - * goes away. (The references will be held on the "proxy" side, while - * the Layer exists on the "native" side.) + * The layer handle is just a BBinder object passed to the client + * (remote process) -- we don't keep any reference on our side such that + * the dtor is called when the remote side let go of its reference. * - * The Layer has a reference to an instance of SurfaceFlinger's variant - * of GLConsumer, which holds a reference to the BufferQueue. The - * getSurfaceTexture() call returns a Binder interface reference for - * the producer interface of the buffer queue associated with the Layer. + * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for + * this layer when the handle is destroyed. */ - class BSurface : public BnSurface, public LayerCleaner { + + class Handle : public BBinder, public LayerCleaner { wp<const Layer> mOwner; - virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { - sp<IGraphicBufferProducer> res; - sp<const Layer> that( mOwner.promote() ); - if (that != NULL) { - res = that->mSurfaceFlingerConsumer->getBufferQueue(); - } - return res; - } public: - BSurface(const sp<SurfaceFlinger>& flinger, - const sp<Layer>& layer) - : LayerCleaner(flinger, layer), mOwner(layer) { } + Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer) + : LayerCleaner(flinger, layer), mOwner(layer) { + } }; - sp<ISurface> sur(new BSurface(mFlinger, this)); - return sur; -} -wp<IBinder> Layer::getSurfaceTextureBinder() const { - return mSurfaceFlingerConsumer->getBufferQueue()->asBinder(); + return new Handle(mFlinger, this); } -sp<ISurface> Layer::getSurface() -{ - sp<ISurface> s; - Mutex::Autolock _l(mLock); - - LOG_ALWAYS_FATAL_IF(mHasSurface, - "Layer::getSurface() has already been called"); - - mHasSurface = true; - s = createSurface(); - return s; +sp<BufferQueue> Layer::getBufferQueue() const { + return mSurfaceFlingerConsumer->getBufferQueue(); } +//virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { +// sp<IGraphicBufferProducer> res; +// sp<const Layer> that( mOwner.promote() ); +// if (that != NULL) { +// res = that->mSurfaceFlingerConsumer->getBufferQueue(); +// } +// return res; +//} + // --------------------------------------------------------------------------- // h/w composer set-up // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 5fb6d8b682..6bca9413a7 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -124,16 +124,12 @@ public: // ----------------------------------------------------------------------- - Layer(SurfaceFlinger* flinger, const sp<Client>& client); + Layer(SurfaceFlinger* flinger, const sp<Client>& client, + const String8& name, uint32_t w, uint32_t h, uint32_t flags); virtual ~Layer(); // the this layer's size and format - status_t setBuffers(uint32_t w, uint32_t h, - PixelFormat format, uint32_t flags=0); - - // Creates an ISurface associated with this object. This may only be - // called once. to provide your own ISurface, override createSurface(). - sp<ISurface> getSurface(); + status_t setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); // modify current state bool setPosition(float x, float y); @@ -154,18 +150,14 @@ public: void computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const; Rect computeBounds() const; - // ----------------------------------------------------------------------- + sp<IBinder> getHandle(); + sp<BufferQueue> getBufferQueue() const; + String8 getName() const; - /* - * initStates - called just after construction - */ - virtual void initStates(uint32_t w, uint32_t h, uint32_t flags); + // ----------------------------------------------------------------------- virtual const char* getTypeId() const { return "Layer"; } - virtual void setName(const String8& name); - String8 getName() const; - virtual void setGeometry(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer); virtual void setPerFrameData(const sp<const DisplayDevice>& hw, @@ -277,8 +269,6 @@ public: virtual void onRemoved(); - virtual wp<IBinder> getSurfaceTextureBinder() const; - // Updates the transform hint in our SurfaceFlingerConsumer to match // the current orientation of the display device. virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const; @@ -336,9 +326,6 @@ protected: private: - // Creates an instance of ISurface for this Layer. - virtual sp<ISurface> createSurface(); - // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener virtual void onFrameAvailable(); @@ -394,7 +381,7 @@ private: // protected by mLock mutable Mutex mLock; - // Set to true if an ISurface has been associated with this object. + // Set to true once we've returned this surface's handle mutable bool mHasSurface; const wp<Client> mClientRef; }; diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp index 23decffe94..36bafdb102 100644 --- a/services/surfaceflinger/LayerDim.cpp +++ b/services/surfaceflinger/LayerDim.cpp @@ -33,8 +33,9 @@ namespace android { // --------------------------------------------------------------------------- -LayerDim::LayerDim(SurfaceFlinger* flinger, const sp<Client>& client) - : Layer(flinger, client) { +LayerDim::LayerDim(SurfaceFlinger* flinger, const sp<Client>& client, + const String8& name, uint32_t w, uint32_t h, uint32_t flags) + : Layer(flinger, client, name, w, h, flags) { } LayerDim::~LayerDim() { @@ -69,19 +70,6 @@ void LayerDim::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) con } } -sp<ISurface> LayerDim::createSurface() -{ - class BSurface : public BnSurface, public LayerCleaner { - virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { return 0; } - public: - BSurface(const sp<SurfaceFlinger>& flinger, - const sp<Layer>& layer) - : LayerCleaner(flinger, layer) { } - }; - sp<ISurface> sur(new BSurface(mFlinger, this)); - return sur; -} - bool LayerDim::isVisible() const { const Layer::State& s(drawingState()); return !(s.flags & layer_state_t::eLayerHidden) && s.alpha; diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h index e1ea9bdf53..e19bf52d69 100644 --- a/services/surfaceflinger/LayerDim.h +++ b/services/surfaceflinger/LayerDim.h @@ -32,7 +32,8 @@ namespace android { class LayerDim : public Layer { public: - LayerDim(SurfaceFlinger* flinger, const sp<Client>& client); + LayerDim(SurfaceFlinger* flinger, const sp<Client>& client, + const String8& name, uint32_t w, uint32_t h, uint32_t flags); virtual ~LayerDim(); virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const; @@ -44,7 +45,6 @@ public: virtual bool isFixedSize() const { return true; } virtual bool isVisible() const; - virtual sp<ISurface> createSurface(); }; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 5939dc85f6..edf01f77da 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -574,40 +574,7 @@ bool SurfaceFlinger::authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& bufferProducer) const { Mutex::Autolock _l(mStateLock); sp<IBinder> surfaceTextureBinder(bufferProducer->asBinder()); - - // We want to determine whether the IGraphicBufferProducer was created by - // SurfaceFlinger. Check to see if we can find it in the layer list. - const LayerVector& currentLayers = mCurrentState.layersSortedByZ; - size_t count = currentLayers.size(); - for (size_t i=0 ; i<count ; i++) { - const sp<Layer>& layer(currentLayers[i]); - // If this is an instance of Layer (as opposed to, say, LayerDim), - // we will get the consumer interface of SurfaceFlingerConsumer's - // BufferQueue. If it's the same Binder object as the graphic - // buffer producer interface, return success. - wp<IBinder> lbcBinder = layer->getSurfaceTextureBinder(); - if (lbcBinder == surfaceTextureBinder) { - return true; - } - } - - // Check the layers in the purgatory. This check is here so that if a - // GLConsumer gets destroyed before all the clients are done using it, - // the error will not be reported as "surface XYZ is not authenticated", but - // will instead fail later on when the client tries to use the surface, - // which should be reported as "surface XYZ returned an -ENODEV". The - // purgatorized layers are no less authentic than the visible ones, so this - // should not cause any harm. - size_t purgatorySize = mLayerPurgatory.size(); - for (size_t i=0 ; i<purgatorySize ; i++) { - const sp<Layer>& layer(mLayerPurgatory.itemAt(i)); - wp<IBinder> lbcBinder = layer->getSurfaceTextureBinder(); - if (lbcBinder == surfaceTextureBinder) { - return true; - } - } - - return false; + return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; } status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) { @@ -1677,6 +1644,7 @@ void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, void SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle, + const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc) { // attach this layer to the client @@ -1685,45 +1653,22 @@ void SurfaceFlinger::addClientLayer(const sp<Client>& client, // add this layer to the current state list Mutex::Autolock _l(mStateLock); mCurrentState.layersSortedByZ.add(lbc); + mGraphicBufferProducerList.add(gbc->asBinder()); } status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) { Mutex::Autolock _l(mStateLock); - status_t err = purgatorizeLayer_l(layer); - if (err == NO_ERROR) - setTransactionFlags(eTransactionNeeded); - return err; -} - -status_t SurfaceFlinger::removeLayer_l(const sp<Layer>& layer) -{ ssize_t index = mCurrentState.layersSortedByZ.remove(layer); if (index >= 0) { + mLayersPendingRemoval.push(layer); mLayersRemoved = true; + setTransactionFlags(eTransactionNeeded); return NO_ERROR; } return status_t(index); } -status_t SurfaceFlinger::purgatorizeLayer_l(const sp<Layer>& layer) -{ - // First add the layer to the purgatory list, which makes sure it won't - // go away, then remove it from the main list (through a transaction). - ssize_t err = removeLayer_l(layer); - if (err >= 0) { - mLayerPurgatory.add(layer); - } - - mLayersPendingRemoval.push(layer); - - // it's possible that we don't find a layer, because it might - // have been destroyed already -- this is not technically an error - // from the user because there is a race between Client::destroySurface(), - // ~Client() and ~ISurface(). - return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; -} - uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) { return android_atomic_release_load(&mTransactionFlags); @@ -1924,48 +1869,49 @@ uint32_t SurfaceFlinger::setClientStateLocked( return flags; } -sp<ISurface> SurfaceFlinger::createLayer( +status_t SurfaceFlinger::createLayer( const String8& name, const sp<Client>& client, - uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags) + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, + sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) { - sp<Layer> layer; - sp<ISurface> surfaceHandle; - + //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); if (int32_t(w|h) < 0) { ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", int(w), int(h)); - return surfaceHandle; + return BAD_VALUE; } - //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); + status_t result = NO_ERROR; + + sp<Layer> layer; + switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { case ISurfaceComposerClient::eFXSurfaceNormal: - layer = createNormalLayer(client, w, h, flags, format); + result = createNormalLayer(client, + name, w, h, flags, format, + handle, gbp, &layer); break; case ISurfaceComposerClient::eFXSurfaceDim: - layer = createDimLayer(client, w, h, flags); + result = createDimLayer(client, + name, w, h, flags, + handle, gbp, &layer); + break; + default: + result = BAD_VALUE; break; } - if (layer != 0) { - layer->initStates(w, h, flags); - layer->setName(name); - surfaceHandle = layer->getSurface(); - if (surfaceHandle != 0) { - addClientLayer(client, surfaceHandle->asBinder(), layer); - } + if (result == NO_ERROR) { + addClientLayer(client, *handle, *gbp, layer); setTransactionFlags(eTransactionNeeded); } - - return surfaceHandle; + return result; } -sp<Layer> SurfaceFlinger::createNormalLayer( - const sp<Client>& client, - uint32_t w, uint32_t h, uint32_t flags, - PixelFormat& format) +status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, + const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, + sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) { // initialize the surfaces switch (format) { @@ -1987,63 +1933,48 @@ sp<Layer> SurfaceFlinger::createNormalLayer( format = PIXEL_FORMAT_RGBA_8888; #endif - sp<Layer> layer = new Layer(this, client); - status_t err = layer->setBuffers(w, h, format, flags); - if (CC_LIKELY(err != NO_ERROR)) { - ALOGE("createNormalLayer() failed (%s)", strerror(-err)); - layer.clear(); + *outLayer = new Layer(this, client, name, w, h, flags); + status_t err = (*outLayer)->setBuffers(w, h, format, flags); + if (err == NO_ERROR) { + *handle = (*outLayer)->getHandle(); + *gbp = (*outLayer)->getBufferQueue(); } - return layer; + + ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err)); + return err; } -sp<LayerDim> SurfaceFlinger::createDimLayer( - const sp<Client>& client, - uint32_t w, uint32_t h, uint32_t flags) +status_t SurfaceFlinger::createDimLayer(const sp<Client>& client, + const String8& name, uint32_t w, uint32_t h, uint32_t flags, + sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) { - sp<LayerDim> layer = new LayerDim(this, client); - return layer; + *outLayer = new LayerDim(this, client, name, w, h, flags); + *handle = (*outLayer)->getHandle(); + *gbp = (*outLayer)->getBufferQueue(); + return NO_ERROR; } status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) { - /* - * called by the window manager, when a surface should be marked for - * destruction. - * - * The surface is removed from the current and drawing lists, but placed - * in the purgatory queue, so it's not destroyed right-away (we need - * to wait for all client's references to go away first). - */ - - status_t err = NAME_NOT_FOUND; - Mutex::Autolock _l(mStateLock); - sp<Layer> layer = client->getLayerUser(handle); - - if (layer != 0) { - err = purgatorizeLayer_l(layer); - if (err == NO_ERROR) { - setTransactionFlags(eTransactionNeeded); - } + // called by the window manager when it wants to remove a Layer + status_t err = NO_ERROR; + sp<Layer> l(client->getLayerUser(handle)); + if (l != NULL) { + err = removeLayer(l); + ALOGE_IF(err<0 && err != NAME_NOT_FOUND, + "error removing layer=%p (%s)", l.get(), strerror(-err)); } return err; } status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) { - // called by ~ISurface() when all references are gone + // called by ~LayerCleaner() when all references to the IBinder (handle) + // are gone status_t err = NO_ERROR; sp<Layer> l(layer.promote()); if (l != NULL) { - Mutex::Autolock _l(mStateLock); - err = removeLayer_l(l); - if (err == NAME_NOT_FOUND) { - // The surface wasn't in the current list, which means it was - // removed already, which means it is in the purgatory, - // and need to be removed from there. - ssize_t idx = mLayerPurgatory.remove(l); - ALOGE_IF(idx < 0, - "layer=%p is not in the purgatory list", l.get()); - } + err = removeLayer(l); ALOGE_IF(err<0 && err != NAME_NOT_FOUND, "error removing layer=%p (%s)", l.get(), strerror(-err)); } @@ -2355,18 +2286,6 @@ void SurfaceFlinger::dumpAllLocked( } /* - * Dump the layers in the purgatory - */ - - const size_t purgatorySize = mLayerPurgatory.size(); - snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); - result.append(buffer); - for (size_t i=0 ; i<purgatorySize ; i++) { - const sp<Layer>& layer(mLayerPurgatory.itemAt(i)); - layer->shortDump(result, buffer, SIZE); - } - - /* * Dump Display state */ @@ -2480,6 +2399,7 @@ status_t SurfaceFlinger::onTransact( { switch (code) { case CREATE_CONNECTION: + case CREATE_DISPLAY: case SET_TRANSACTION_STATE: case BOOT_FINISHED: case BLANK: @@ -2498,6 +2418,7 @@ status_t SurfaceFlinger::onTransact( break; } case CAPTURE_SCREEN: + case CAPTURE_SCREEN_DEPRECATED: { // codes that require permission check IPCThreadState* ipc = IPCThreadState::self(); @@ -2708,15 +2629,19 @@ status_t SurfaceFlinger::captureScreenImplLocked( glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); - const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ()); + const LayerVector& layers( mDrawingState.layersSortedByZ ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { const sp<Layer>& layer(layers[i]); - const uint32_t z = layer->drawingState().z; - if (z >= minLayerZ && z <= maxLayerZ) { - if (filtering) layer->setFiltering(true); - layer->draw(hw); - if (filtering) layer->setFiltering(false); + const Layer::State& state(layer->drawingState()); + if (state.layerStack == hw->getLayerStack()) { + if (state.z >= minLayerZ && state.z <= maxLayerZ) { + if (layer->isVisible()) { + if (filtering) layer->setFiltering(true); + layer->draw(hw); + if (filtering) layer->setFiltering(false); + } + } } } @@ -2781,7 +2706,7 @@ status_t SurfaceFlinger::captureScreenImplLocked( sp<GraphicBuffer> buf(consumer->getCurrentBuffer()); sw = buf->getWidth(); sh = buf->getHeight(); - size_t size = buf->getStride() * sh * 4; + size_t size = sw * sh * 4; // allocate shared memory large enough to hold the // screen capture diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 241a7d635d..e6734d2c1e 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -128,6 +128,7 @@ private: friend class Client; friend class DisplayEventConnection; friend class Layer; + friend class SurfaceTextureLayer; // We're reference counted, never destroy SurfaceFlinger directly virtual ~SurfaceFlinger(); @@ -257,19 +258,21 @@ private: /* ------------------------------------------------------------------------ * Layer management */ - sp<ISurface> createLayer(const String8& name, const sp<Client>& client, - uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); + status_t createLayer(const String8& name, const sp<Client>& client, + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, + sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp); - sp<Layer> createNormalLayer(const sp<Client>& client, - uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format); + status_t createNormalLayer(const sp<Client>& client, const String8& name, + uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, + sp<IBinder>* outHandle, sp<IGraphicBufferProducer>* outGbp, + sp<Layer>* outLayer); - sp<LayerDim> createDimLayer(const sp<Client>& client, - uint32_t w, uint32_t h, uint32_t flags); + status_t createDimLayer(const sp<Client>& client, const String8& name, + uint32_t w, uint32_t h, uint32_t flags, sp<IBinder>* outHandle, + sp<IGraphicBufferProducer>* outGbp, sp<Layer>* outLayer); // called in response to the window-manager calling // ISurfaceComposerClient::destroySurface() - // The specified layer is first placed in a purgatory list - // until all references from the client are released. status_t onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle); // called when all clients have released all their references to @@ -281,11 +284,10 @@ private: status_t removeLayer(const sp<Layer>& layer); // add a layer to SurfaceFlinger - void addClientLayer(const sp<Client>& client, const sp<IBinder>& handle, - const sp<Layer>& lbc); - - status_t removeLayer_l(const sp<Layer>& layer); - status_t purgatorizeLayer_l(const sp<Layer>& layer); + void addClientLayer(const sp<Client>& client, + const sp<IBinder>& handle, + const sp<IGraphicBufferProducer>& gbc, + const sp<Layer>& lbc); /* ------------------------------------------------------------------------ * Boot animation, on/off animations and screen capture @@ -399,10 +401,10 @@ private: State mCurrentState; volatile int32_t mTransactionFlags; Condition mTransactionCV; - SortedVector< sp<Layer> > mLayerPurgatory; bool mTransactionPending; bool mAnimTransactionPending; Vector< sp<Layer> > mLayersPendingRemoval; + SortedVector< wp<IBinder> > mGraphicBufferProducerList; // protected by mStateLock (but we could use another lock) bool mLayersRemoved; diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp index 395c8c8353..d0f0daec99 100644 --- a/services/surfaceflinger/SurfaceTextureLayer.cpp +++ b/services/surfaceflinger/SurfaceTextureLayer.cpp @@ -20,17 +20,35 @@ #include <utils/Errors.h> +#include "SurfaceFlinger.h" #include "SurfaceTextureLayer.h" namespace android { // --------------------------------------------------------------------------- -SurfaceTextureLayer::SurfaceTextureLayer() - : BufferQueue(true) { +SurfaceTextureLayer::SurfaceTextureLayer(const sp<SurfaceFlinger>& flinger) + : BufferQueue(true), flinger(flinger) { } SurfaceTextureLayer::~SurfaceTextureLayer() { + // remove ourselves from SurfaceFlinger's list. We do this asynchronously + // because we don't know where this dtor is called from, it could be + // called with the mStateLock held, leading to a dead-lock (it actually + // happens). + class MessageCleanUpList : public MessageBase { + sp<SurfaceFlinger> flinger; + wp<IBinder> gbp; + public: + MessageCleanUpList(const sp<SurfaceFlinger>& flinger, const wp<IBinder>& gbp) + : flinger(flinger), gbp(gbp) { } + virtual bool handler() { + Mutex::Autolock _l(flinger->mStateLock); + flinger->mGraphicBufferProducerList.remove(gbp); + return true; + } + }; + flinger->postMessageAsync( new MessageCleanUpList(flinger, this) ); } status_t SurfaceTextureLayer::connect(int api, QueueBufferOutput* output) { diff --git a/services/surfaceflinger/SurfaceTextureLayer.h b/services/surfaceflinger/SurfaceTextureLayer.h index a75ccf47d2..13cff2fff8 100644 --- a/services/surfaceflinger/SurfaceTextureLayer.h +++ b/services/surfaceflinger/SurfaceTextureLayer.h @@ -28,15 +28,16 @@ namespace android { // --------------------------------------------------------------------------- class Layer; +class SurfaceFlinger; /* * This is a thin wrapper around BufferQueue, used by the Layer class. */ -class SurfaceTextureLayer : public BufferQueue -{ +class SurfaceTextureLayer : public BufferQueue { + sp<SurfaceFlinger> flinger; public: - SurfaceTextureLayer(); - ~SurfaceTextureLayer(); + SurfaceTextureLayer(const sp<SurfaceFlinger>& flinger); + virtual ~SurfaceTextureLayer(); // After calling the superclass connect(), set or clear synchronous // mode appropriately for the specified API. diff --git a/services/surfaceflinger/tests/surface/Android.mk b/services/surfaceflinger/tests/surface/Android.mk deleted file mode 100644 index c59060e173..0000000000 --- a/services/surfaceflinger/tests/surface/Android.mk +++ /dev/null @@ -1,18 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - surface.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libutils \ - libbinder \ - libui \ - libgui - -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 deleted file mode 100644 index 9c41cc3447..0000000000 --- a/services/surfaceflinger/tests/surface/surface.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - */ - -#include <cutils/memory.h> - -#include <utils/Log.h> - -#include <binder/IPCThreadState.h> -#include <binder/ProcessState.h> -#include <binder/IServiceManager.h> - -#include <gui/Surface.h> -#include <gui/SurfaceComposerClient.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(); - - sp<SurfaceControl> surfaceControl = client->createSurface( - String8("surface"), 160, 240, PIXEL_FORMAT_RGB_565, 0); - SurfaceComposerClient::openGlobalTransaction(); - surfaceControl->setLayer(100000); - SurfaceComposerClient::closeGlobalTransaction(); - - // 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); - ANativeWindowBuffer* 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; -} |