diff options
64 files changed, 2087 insertions, 1856 deletions
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp index c6b3dce2d7..c6fda97721 100644 --- a/cmds/atrace/atrace.cpp +++ b/cmds/atrace/atrace.cpp @@ -77,6 +77,7 @@ static const TracingCategory k_categories[] = { { "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" }, diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c index c8eafb8960..1b8f755b8e 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -196,13 +196,13 @@ static void dumpstate() { property_get("dhcp.wlan0.gateway", network, ""); if (network[0]) - run_command("PING GATEWAY", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL); + run_command("PING GATEWAY", 10, "ping", "-c", "3", "-i", ".5", network, NULL); property_get("dhcp.wlan0.dns1", network, ""); if (network[0]) - run_command("PING DNS1", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL); + run_command("PING DNS1", 10, "ping", "-c", "3", "-i", ".5", network, NULL); property_get("dhcp.wlan0.dns2", network, ""); if (network[0]) - run_command("PING DNS2", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL); + run_command("PING DNS2", 10, "ping", "-c", "3", "-i", ".5", network, NULL); #ifdef FWDUMP_bcmdhd run_command("DUMP WIFI STATUS", 20, SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL); diff --git a/cmds/flatland/GLHelper.cpp b/cmds/flatland/GLHelper.cpp index 31b1e063fa..4f7697f4a7 100644 --- a/cmds/flatland/GLHelper.cpp +++ b/cmds/flatland/GLHelper.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#include <ui/Fence.h> - #include <ui/DisplayInfo.h> #include <gui/SurfaceComposerClient.h> @@ -207,7 +205,7 @@ bool GLHelper::createNamedSurfaceTexture(GLuint name, uint32_t w, uint32_t h, glc->setDefaultMaxBufferCount(3); glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER); - sp<ANativeWindow> anw = new SurfaceTextureClient(bq); + sp<ANativeWindow> anw = new Surface(bq); EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), NULL); if (s == EGL_NO_SURFACE) { fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError()); diff --git a/cmds/flatland/GLHelper.h b/cmds/flatland/GLHelper.h index 19fdff9863..7a9e9e3ea2 100644 --- a/cmds/flatland/GLHelper.h +++ b/cmds/flatland/GLHelper.h @@ -16,7 +16,8 @@ #include <gui/GraphicBufferAlloc.h> #include <gui/GLConsumer.h> -#include <gui/SurfaceTextureClient.h> +#include <gui/Surface.h> +#include <gui/SurfaceControl.h> #include <EGL/egl.h> #include <GLES2/gl2.h> diff --git a/cmds/flatland/Main.cpp b/cmds/flatland/Main.cpp index 45f414e4fe..99715d39d6 100644 --- a/cmds/flatland/Main.cpp +++ b/cmds/flatland/Main.cpp @@ -18,8 +18,9 @@ #include <gui/GraphicBufferAlloc.h> #include <gui/Surface.h> +#include <gui/SurfaceControl.h> #include <gui/GLConsumer.h> -#include <gui/SurfaceTextureClient.h> +#include <gui/Surface.h> #include <ui/Fence.h> #include <utils/Trace.h> diff --git a/include/android/configuration.h b/include/android/configuration.h index 0f5c14afad..d5cddb3069 100644 --- a/include/android/configuration.h +++ b/include/android/configuration.h @@ -44,6 +44,7 @@ enum { ACONFIGURATION_DENSITY_HIGH = 240, ACONFIGURATION_DENSITY_XHIGH = 320, ACONFIGURATION_DENSITY_XXHIGH = 480, + ACONFIGURATION_DENSITY_XXXHIGH = 640, ACONFIGURATION_DENSITY_NONE = 0xffff, ACONFIGURATION_KEYBOARD_ANY = 0x0000, diff --git a/include/binder/AppOpsManager.h b/include/binder/AppOpsManager.h new file mode 100644 index 0000000000..256cb949bb --- /dev/null +++ b/include/binder/AppOpsManager.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2013 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_APP_OPS_MANAGER_H +#define ANDROID_APP_OPS_MANAGER_H + +#include <binder/IAppOpsService.h> + +#include <utils/threads.h> + +// --------------------------------------------------------------------------- +namespace android { + +class AppOpsManager +{ +public: + enum { + MODE_ALLOWED = IAppOpsService::MODE_ALLOWED, + MODE_IGNORED = IAppOpsService::MODE_IGNORED, + MODE_ERRORED = IAppOpsService::MODE_ERRORED + }; + + enum { + OP_NONE = -1, + OP_COARSE_LOCATION = 0, + OP_FINE_LOCATION = 1, + OP_GPS = 2, + OP_VIBRATE = 3, + OP_READ_CONTACTS = 4, + OP_WRITE_CONTACTS = 5, + OP_READ_CALL_LOG = 6, + OP_WRITE_CALL_LOG = 7, + OP_READ_CALENDAR = 8, + OP_WRITE_CALENDAR = 9, + OP_WIFI_SCAN = 10, + OP_POST_NOTIFICATION = 11, + OP_NEIGHBORING_CELLS = 12, + OP_CALL_PHONE = 13, + OP_READ_SMS = 14, + OP_WRITE_SMS = 15, + OP_RECEIVE_SMS = 16, + OP_RECEIVE_EMERGECY_SMS = 17, + OP_RECEIVE_MMS = 18, + OP_RECEIVE_WAP_PUSH = 19, + OP_SEND_SMS = 20, + OP_READ_ICC_SMS = 21, + OP_WRITE_ICC_SMS = 22, + OP_WRITE_SETTINGS = 23, + OP_SYSTEM_ALERT_WINDOW = 24, + OP_ACCESS_NOTIFICATIONS = 25, + OP_CAMERA = 26, + OP_RECORD_AUDIO = 27, + OP_PLAY_AUDIO = 28 + }; + + AppOpsManager(); + + int32_t checkOp(int32_t op, int32_t uid, const String16& callingPackage); + int32_t noteOp(int32_t op, int32_t uid, const String16& callingPackage); + int32_t startOp(int32_t op, int32_t uid, const String16& callingPackage); + void finishOp(int32_t op, int32_t uid, const String16& callingPackage); + void startWatchingMode(int32_t op, const String16& packageName, + const sp<IAppOpsCallback>& callback); + void stopWatchingMode(const sp<IAppOpsCallback>& callback); + +private: + Mutex mLock; + sp<IAppOpsService> mService; + + sp<IAppOpsService> getService(); +}; + + +}; // namespace android +// --------------------------------------------------------------------------- +#endif // ANDROID_APP_OPS_MANAGER_H diff --git a/include/binder/IAppOpsCallback.h b/include/binder/IAppOpsCallback.h new file mode 100644 index 0000000000..7f8eb0168b --- /dev/null +++ b/include/binder/IAppOpsCallback.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013 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_IAPP_OPS_CALLBACK_H +#define ANDROID_IAPP_OPS_CALLBACK_H + +#include <binder/IInterface.h> + +namespace android { + +// ---------------------------------------------------------------------- + +class IAppOpsCallback : public IInterface +{ +public: + DECLARE_META_INTERFACE(AppOpsCallback); + + virtual void opChanged(int32_t op, const String16& packageName) = 0; + + enum { + OP_CHANGED_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + }; +}; + +// ---------------------------------------------------------------------- + +class BnAppOpsCallback : public BnInterface<IAppOpsCallback> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IAPP_OPS_CALLBACK_H + diff --git a/include/binder/IAppOpsService.h b/include/binder/IAppOpsService.h new file mode 100644 index 0000000000..7cb55e5dab --- /dev/null +++ b/include/binder/IAppOpsService.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2013 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_IAPP_OPS_SERVICE_H +#define ANDROID_IAPP_OPS_SERVICE_H + +#include <binder/IAppOpsCallback.h> +#include <binder/IInterface.h> + +namespace android { + +// ---------------------------------------------------------------------- + +class IAppOpsService : public IInterface +{ +public: + DECLARE_META_INTERFACE(AppOpsService); + + virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) = 0; + virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName) = 0; + virtual int32_t startOperation(int32_t code, int32_t uid, const String16& packageName) = 0; + virtual void finishOperation(int32_t code, int32_t uid, const String16& packageName) = 0; + virtual void startWatchingMode(int32_t op, const String16& packageName, + const sp<IAppOpsCallback>& callback) = 0; + virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0; + + enum { + CHECK_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, + NOTE_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+1, + START_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+2, + FINISH_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+3, + START_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+4, + STOP_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+5 + }; + + enum { + MODE_ALLOWED = 0, + MODE_IGNORED = 1, + MODE_ERRORED = 2 + }; +}; + +// ---------------------------------------------------------------------- + +class BnAppOpsService : public BnInterface<IAppOpsService> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IAPP_OPS_SERVICE_H diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h index f230b8d646..a3e258df3a 100644 --- a/include/gui/IGraphicBufferProducer.h +++ b/include/gui/IGraphicBufferProducer.h @@ -32,14 +32,14 @@ namespace android { // ---------------------------------------------------------------------------- -class SurfaceTextureClient; +class Surface; /* * This class defines the Binder IPC interface for the producer side of * a queue of graphics buffers. It's used to send graphics data from one * component to another. For example, a class that decodes video for * playback might use this to provide frames. This is typically done - * indirectly, through SurfaceTextureClient. + * indirectly, through Surface. * * The underlying mechanism is a BufferQueue, which implements * BnGraphicBufferProducer. In normal operation, the producer calls diff --git a/include/gui/ISurface.h b/include/gui/ISurface.h index ce6e715b3b..5a928f20bc 100644 --- a/include/gui/ISurface.h +++ b/include/gui/ISurface.h @@ -29,8 +29,6 @@ namespace android { -typedef int32_t SurfaceID; - class IGraphicBufferProducer; class ISurface : public IInterface diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h index e256e33454..23d1d4c1b9 100644 --- a/include/gui/ISurfaceComposerClient.h +++ b/include/gui/ISurfaceComposerClient.h @@ -54,24 +54,17 @@ public: eFXSurfaceMask = 0x000F0000, }; - struct surface_data_t { - int32_t token; - int32_t identity; - status_t readFromParcel(const Parcel& parcel); - status_t writeToParcel(Parcel* parcel) const; - }; - /* * Requires ACCESS_SURFACE_FLINGER permission */ - virtual sp<ISurface> createSurface(surface_data_t* data, + virtual sp<ISurface> createSurface( const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) = 0; /* * Requires ACCESS_SURFACE_FLINGER permission */ - virtual status_t destroySurface(SurfaceID sid) = 0; + virtual status_t destroySurface(const sp<IBinder>& handle) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/Surface.h b/include/gui/Surface.h index 8654f76aba..18e57ed9ed 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * 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. @@ -17,163 +17,246 @@ #ifndef ANDROID_GUI_SURFACE_H #define ANDROID_GUI_SURFACE_H -#include <stdint.h> -#include <sys/types.h> +#include <gui/IGraphicBufferProducer.h> +#include <gui/GLConsumer.h> +#include <gui/BufferQueue.h> -#include <utils/KeyedVector.h> -#include <utils/RefBase.h> -#include <utils/threads.h> - -#include <ui/PixelFormat.h> +#include <ui/ANativeObjectBase.h> #include <ui/Region.h> -#include <gui/SurfaceTextureClient.h> -#include <gui/ISurface.h> -#include <gui/ISurfaceComposerClient.h> +#include <utils/RefBase.h> +#include <utils/threads.h> +#include <utils/KeyedVector.h> -#define ANDROID_VIEW_SURFACE_JNI_ID "mNativeSurface" +struct ANativeWindow_Buffer; namespace android { -// --------------------------------------------------------------------------- - -class IGraphicBufferProducer; -class Surface; -class SurfaceComposerClient; - -// --------------------------------------------------------------------------- - -class SurfaceControl : public RefBase -{ -public: - static bool isValid(const sp<SurfaceControl>& surface) { - return (surface != 0) && surface->isValid(); - } - bool isValid() { - return mToken>=0 && mClient!=0; - } - static bool isSameSurface( - const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs); - - uint32_t getIdentity() const { return mIdentity; } - - // release surface data from java - void clear(); - - status_t setLayerStack(int32_t layerStack); - status_t setLayer(int32_t layer); - status_t setPosition(int32_t x, int32_t y); - status_t setSize(uint32_t w, uint32_t h); - status_t hide(); - status_t show(); - status_t setFlags(uint32_t flags, uint32_t mask); - status_t setTransparentRegionHint(const Region& transparent); - status_t setAlpha(float alpha=1.0f); - status_t setMatrix(float dsdx, float dtdx, float dsdy, float dtdy); - status_t setCrop(const Rect& crop); - - static status_t writeSurfaceToParcel( - const sp<SurfaceControl>& control, Parcel* parcel); - - sp<Surface> getSurface() const; - -private: - // can't be copied - SurfaceControl& operator = (SurfaceControl& rhs); - SurfaceControl(const SurfaceControl& rhs); - - friend class SurfaceComposerClient; - friend class Surface; - - SurfaceControl( - const sp<SurfaceComposerClient>& client, - const sp<ISurface>& surface, - const ISurfaceComposerClient::surface_data_t& data); - - ~SurfaceControl(); - - status_t validate() const; - void destroy(); - - sp<SurfaceComposerClient> mClient; - sp<ISurface> mSurface; - SurfaceID mToken; - uint32_t mIdentity; - mutable Mutex mLock; - - mutable sp<Surface> mSurfaceData; -}; - -// --------------------------------------------------------------------------- - /* - * This is a small wrapper around SurfaceTextureClient. + * An implementation of ANativeWindow that feeds graphics buffers into a + * BufferQueue. * - * TODO: rename and/or merge with STC. + * This is typically used by programs that want to render frames through + * some means (maybe OpenGL, a software renderer, or a hardware decoder) + * and have the frames they create forwarded to SurfaceFlinger for + * compositing. For example, a video decoder could render a frame and call + * eglSwapBuffers(), which invokes ANativeWindow callbacks defined by + * Surface. Surface then forwards the buffers through Binder IPC + * to the BufferQueue's producer interface, providing the new frame to a + * consumer such as GLConsumer. */ -class Surface : public SurfaceTextureClient +class Surface + : public ANativeObjectBase<ANativeWindow, Surface, RefBase> { public: - struct SurfaceInfo { - uint32_t w; - uint32_t h; - uint32_t s; - uint32_t usage; - PixelFormat format; - void* bits; - uint32_t reserved[2]; - }; - explicit Surface(const sp<IGraphicBufferProducer>& bp); + /* + * creates a Surface from the given IGraphicBufferProducer (which concrete + * implementation is a BufferQueue). + * + * Surface is mainly state-less while it's disconnected, it can be + * viewed as a glorified IGraphicBufferProducer holder. It's therefore + * safe to create other Surfaces from the same IGraphicBufferProducer. + * + * However, once a Surface is connected, it'll prevent other Surfaces + * referring to the same IGraphicBufferProducer to become connected and + * therefore prevent them to be used as actual producers of buffers. + */ + Surface(const sp<IGraphicBufferProducer>& bufferProducer); - static status_t writeToParcel(const sp<Surface>& control, Parcel* parcel); + /* getIGraphicBufferProducer() returns the IGraphicBufferProducer this + * Surface was created with. Usually it's an error to use the + * IGraphicBufferProducer while the Surface is connected. + */ + sp<IGraphicBufferProducer> getIGraphicBufferProducer() const; - static sp<Surface> readFromParcel(const Parcel& data); + /* convenience function to check that the given surface is non NULL as + * well as its IGraphicBufferProducer */ static bool isValid(const sp<Surface>& surface) { - return (surface != 0) && surface->isValid(); + return surface != NULL && surface->getIGraphicBufferProducer() != NULL; } - bool isValid(); - uint32_t getIdentity() const { return mIdentity; } - sp<IGraphicBufferProducer> getSurfaceTexture(); // TODO: rename this + /* 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); - // the lock/unlock APIs must be used from the same thread - status_t lock(SurfaceInfo* info, Region* dirty = NULL); - status_t unlockAndPost(); - sp<IBinder> asBinder() const; +protected: + Surface(); + virtual ~Surface(); + void setIGraphicBufferProducer(const sp<IGraphicBufferProducer>& bufferProducer); private: - // this is just to be able to write some unit tests - friend class Test; - friend class SurfaceControl; - // can't be copied - Surface& operator = (Surface& rhs); + Surface& operator = (const Surface& rhs); Surface(const Surface& rhs); + void init(); + + // ANativeWindow hooks + static int hook_cancelBuffer(ANativeWindow* window, + ANativeWindowBuffer* buffer, int fenceFd); + static int hook_dequeueBuffer(ANativeWindow* window, + ANativeWindowBuffer** buffer, int* fenceFd); + static int hook_perform(ANativeWindow* window, int operation, ...); + static int hook_query(const ANativeWindow* window, int what, int* value); + static int hook_queueBuffer(ANativeWindow* window, + ANativeWindowBuffer* buffer, int fenceFd); + static int hook_setSwapInterval(ANativeWindow* window, int interval); + + static int hook_cancelBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + static int hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer** buffer); + static int hook_lockBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + static int hook_queueBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + + int dispatchConnect(va_list args); + int dispatchDisconnect(va_list args); + int dispatchSetBufferCount(va_list args); + int dispatchSetBuffersGeometry(va_list args); + int dispatchSetBuffersDimensions(va_list args); + int dispatchSetBuffersUserDimensions(va_list args); + int dispatchSetBuffersFormat(va_list args); + int dispatchSetScalingMode(va_list args); + int dispatchSetBuffersTransform(va_list args); + int dispatchSetBuffersTimestamp(va_list args); + int dispatchSetCrop(va_list args); + int dispatchSetPostTransformCrop(va_list args); + int dispatchSetUsage(va_list args); + int dispatchLock(va_list args); + int dispatchUnlockAndPost(va_list args); + +protected: + virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd); + virtual int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd); + virtual int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd); + virtual int perform(int operation, va_list args); + virtual int query(int what, int* value) const; + virtual int setSwapInterval(int interval); + + virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer); + + virtual int connect(int api); + virtual int disconnect(int api); + virtual int setBufferCount(int bufferCount); + virtual int setBuffersDimensions(int w, int h); + virtual int setBuffersUserDimensions(int w, int h); + virtual int setBuffersFormat(int format); + virtual int setScalingMode(int mode); + virtual int setBuffersTransform(int transform); + virtual int setBuffersTimestamp(int64_t timestamp); + virtual int setCrop(Rect const* rect); + virtual int setUsage(uint32_t reqUsage); - explicit Surface(const sp<SurfaceControl>& control); - Surface(const Parcel& data, const sp<IBinder>& ref); - ~Surface(); - - /* - * private stuff... - */ - void init(const sp<IGraphicBufferProducer>& bufferProducer); +public: + virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); + virtual int unlockAndPost(); - static void cleanCachedSurfacesLocked(); +protected: + enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS }; + enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; - virtual int query(int what, int* value) const; +private: + void freeAllBuffers(); + int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; - // constants - sp<ISurface> mSurface; - uint32_t mIdentity; + struct BufferSlot { + sp<GraphicBuffer> buffer; + Region dirtyRegion; + }; - // A cache of Surface objects that have been deserialized into this process. - static Mutex sCachedSurfacesLock; - static DefaultKeyedVector<wp<IBinder>, wp<Surface> > sCachedSurfaces; + // mSurfaceTexture is the interface to the surface texture server. All + // operations on the surface texture client ultimately translate into + // interactions with the server using this interface. + // TODO: rename to mBufferProducer + sp<IGraphicBufferProducer> mGraphicBufferProducer; + + // mSlots stores the buffers that have been allocated for each buffer slot. + // It is initialized to null pointers, and gets filled in with the result of + // IGraphicBufferProducer::requestBuffer when the client dequeues a buffer from a + // slot that has not yet been used. The buffer allocated to a slot will also + // be replaced if the requested buffer usage or geometry differs from that + // of the buffer allocated to a slot. + BufferSlot mSlots[NUM_BUFFER_SLOTS]; + + // mReqWidth is the buffer width that will be requested at the next dequeue + // operation. It is initialized to 1. + uint32_t mReqWidth; + + // 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 + // deuque operation. It is initialized to PIXEL_FORMAT_RGBA_8888. + uint32_t mReqFormat; + + // mReqUsage is the set of buffer usage flags that will be requested + // at the next deuque operation. It is initialized to 0. + uint32_t mReqUsage; + + // mTimestamp is the timestamp that will be used for the next buffer queue + // operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that + // 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 buffers, regardless of the + // native_window_set_buffers_dimensions call. + uint32_t mDefaultWidth; + + // mDefaultHeight is default height of the buffers, regardless of the + // native_window_set_buffers_dimensions call. + uint32_t mDefaultHeight; + + // mUserWidth, if non-zero, is an application-specified override + // of mDefaultWidth. This is lower priority than the width set by + // native_window_set_buffers_dimensions. + uint32_t mUserWidth; + + // mUserHeight, if non-zero, is an application-specified override + // of mDefaultHeight. This is lower priority than the height set + // by native_window_set_buffers_dimensions. + uint32_t mUserHeight; + + // mTransformHint is the transform probably applied to buffers of this + // window. this is only a hint, actual transform may differ. + uint32_t mTransformHint; + + // mConsumerRunningBehind whether the consumer is running more than + // one buffer behind the producer. + mutable bool mConsumerRunningBehind; + + // mMutex is the mutex used to prevent concurrent access to the member + // variables of Surface objects. It must be locked whenever the + // member variables are accessed. + mutable Mutex mMutex; + + // must be used from the lock/unlock thread + sp<GraphicBuffer> mLockedBuffer; + sp<GraphicBuffer> mPostedBuffer; + bool mConnectedToCpu; + + // must be accessed from lock/unlock thread only + Region mDirtyRegion; }; }; // namespace android -#endif // ANDROID_GUI_SURFACE_H +#endif // ANDROID_GUI_SURFACE_H diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index 22e6b14e07..9e4d6fc301 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -21,6 +21,7 @@ #include <sys/types.h> #include <binder/IBinder.h> +#include <binder/IMemory.h> #include <utils/RefBase.h> #include <utils/Singleton.h> @@ -29,7 +30,7 @@ #include <ui/PixelFormat.h> -#include <gui/Surface.h> +#include <gui/SurfaceControl.h> namespace android { @@ -108,18 +109,18 @@ public: //! Flag the currently open transaction as an animation transaction. static void setAnimationTransaction(); - status_t hide(SurfaceID id); - status_t show(SurfaceID id); - status_t setFlags(SurfaceID id, uint32_t flags, uint32_t mask); - status_t setTransparentRegionHint(SurfaceID id, const Region& transparent); - status_t setLayer(SurfaceID id, int32_t layer); - status_t setAlpha(SurfaceID id, float alpha=1.0f); - status_t setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy); - status_t setPosition(SurfaceID id, float x, float y); - status_t setSize(SurfaceID id, uint32_t w, uint32_t h); - status_t setCrop(SurfaceID id, const Rect& crop); - status_t setLayerStack(SurfaceID id, uint32_t layerStack); - status_t destroySurface(SurfaceID sid); + status_t hide(const sp<IBinder>& id); + status_t show(const sp<IBinder>& id); + status_t setFlags(const sp<IBinder>& id, uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(const sp<IBinder>& id, const Region& transparent); + status_t setLayer(const sp<IBinder>& id, int32_t layer); + status_t setAlpha(const sp<IBinder>& id, float alpha=1.0f); + status_t setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dsdy, float dtdy); + status_t setPosition(const sp<IBinder>& id, float x, float y); + status_t setSize(const sp<IBinder>& id, uint32_t w, uint32_t h); + status_t setCrop(const sp<IBinder>& id, const Rect& crop); + status_t setLayerStack(const sp<IBinder>& id, uint32_t layerStack); + status_t destroySurface(const sp<IBinder>& id); static void setDisplaySurface(const sp<IBinder>& token, const sp<IGraphicBufferProducer>& bufferProducer); diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h new file mode 100644 index 0000000000..9268e7dc87 --- /dev/null +++ b/include/gui/SurfaceControl.h @@ -0,0 +1,101 @@ +/* + * 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_SURFACE_CONTROL_H +#define ANDROID_GUI_SURFACE_CONTROL_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/KeyedVector.h> +#include <utils/RefBase.h> +#include <utils/threads.h> + +#include <ui/PixelFormat.h> +#include <ui/Region.h> + +#include <gui/ISurface.h> +#include <gui/ISurfaceComposerClient.h> + +namespace android { + +// --------------------------------------------------------------------------- + +class IGraphicBufferProducer; +class Surface; +class SurfaceComposerClient; + +// --------------------------------------------------------------------------- + +class SurfaceControl : public RefBase +{ +public: + static bool isValid(const sp<SurfaceControl>& surface) { + return (surface != 0) && surface->isValid(); + } + bool isValid() { + return mSurface!=0 && mClient!=0; + } + static bool isSameSurface( + const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs); + + // release surface data from java + void clear(); + + status_t setLayerStack(int32_t layerStack); + status_t setLayer(int32_t layer); + status_t setPosition(float x, float y); + status_t setSize(uint32_t w, uint32_t h); + status_t hide(); + status_t show(); + status_t setFlags(uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(const Region& transparent); + status_t setAlpha(float alpha=1.0f); + status_t setMatrix(float dsdx, float dtdx, float dsdy, float dtdy); + status_t setCrop(const Rect& crop); + + static status_t writeSurfaceToParcel( + const sp<SurfaceControl>& control, Parcel* parcel); + + sp<Surface> getSurface() const; + +private: + // can't be copied + SurfaceControl& operator = (SurfaceControl& rhs); + SurfaceControl(const SurfaceControl& rhs); + + friend class SurfaceComposerClient; + friend class Surface; + + SurfaceControl( + const sp<SurfaceComposerClient>& client, + const sp<ISurface>& surface); + + ~SurfaceControl(); + + status_t validate() const; + void destroy(); + + sp<SurfaceComposerClient> mClient; + sp<IBinder> mSurface; + sp<IGraphicBufferProducer> mGraphicBufferProducer; + mutable Mutex mLock; + mutable sp<Surface> mSurfaceData; +}; + +}; // namespace android + +#endif // ANDROID_GUI_SURFACE_CONTROL_H diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h deleted file mode 100644 index 6f09821926..0000000000 --- a/include/gui/SurfaceTextureClient.h +++ /dev/null @@ -1,234 +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. - */ - -#ifndef ANDROID_GUI_SURFACETEXTURECLIENT_H -#define ANDROID_GUI_SURFACETEXTURECLIENT_H - -#include <gui/IGraphicBufferProducer.h> -#include <gui/GLConsumer.h> -#include <gui/BufferQueue.h> - -#include <ui/ANativeObjectBase.h> -#include <ui/Region.h> - -#include <utils/RefBase.h> -#include <utils/threads.h> -#include <utils/KeyedVector.h> - -struct ANativeWindow_Buffer; - -namespace android { - -class Surface; - -/* - * An implementation of ANativeWindow that feeds graphics buffers into a - * BufferQueue. - * - * This is typically used by programs that want to render frames through - * some means (maybe OpenGL, a software renderer, or a hardware decoder) - * and have the frames they create forwarded to SurfaceFlinger for - * compositing. For example, a video decoder could render a frame and call - * eglSwapBuffers(), which invokes ANativeWindow callbacks defined by - * SurfaceTextureClient. STC then forwards the buffers through Binder IPC - * to the BufferQueue's producer interface, providing the new frame to a - * consumer such as GLConsumer. - * - * TODO: rename to Surface after merging or renaming the existing Surface - * class. - */ -class SurfaceTextureClient - : public ANativeObjectBase<ANativeWindow, SurfaceTextureClient, RefBase> -{ -public: - - SurfaceTextureClient(const sp<IGraphicBufferProducer>& bufferProducer); - - sp<IGraphicBufferProducer> getISurfaceTexture() const; // TODO: rename - -protected: - SurfaceTextureClient(); - virtual ~SurfaceTextureClient(); - void setISurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer); - -private: - // can't be copied - SurfaceTextureClient& operator = (const SurfaceTextureClient& rhs); - SurfaceTextureClient(const SurfaceTextureClient& rhs); - void init(); - - // ANativeWindow hooks - static int hook_cancelBuffer(ANativeWindow* window, - ANativeWindowBuffer* buffer, int fenceFd); - static int hook_dequeueBuffer(ANativeWindow* window, - ANativeWindowBuffer** buffer, int* fenceFd); - static int hook_perform(ANativeWindow* window, int operation, ...); - static int hook_query(const ANativeWindow* window, int what, int* value); - static int hook_queueBuffer(ANativeWindow* window, - ANativeWindowBuffer* buffer, int fenceFd); - static int hook_setSwapInterval(ANativeWindow* window, int interval); - - static int hook_cancelBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer* buffer); - static int hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer** buffer); - static int hook_lockBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer* buffer); - static int hook_queueBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer* buffer); - - int dispatchConnect(va_list args); - int dispatchDisconnect(va_list args); - int dispatchSetBufferCount(va_list args); - int dispatchSetBuffersGeometry(va_list args); - int dispatchSetBuffersDimensions(va_list args); - int dispatchSetBuffersUserDimensions(va_list args); - int dispatchSetBuffersFormat(va_list args); - int dispatchSetScalingMode(va_list args); - int dispatchSetBuffersTransform(va_list args); - int dispatchSetBuffersTimestamp(va_list args); - int dispatchSetCrop(va_list args); - int dispatchSetPostTransformCrop(va_list args); - int dispatchSetUsage(va_list args); - int dispatchLock(va_list args); - int dispatchUnlockAndPost(va_list args); - -protected: - virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd); - virtual int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd); - virtual int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd); - virtual int perform(int operation, va_list args); - virtual int query(int what, int* value) const; - virtual int setSwapInterval(int interval); - - virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer); - - virtual int connect(int api); - virtual int disconnect(int api); - virtual int setBufferCount(int bufferCount); - virtual int setBuffersDimensions(int w, int h); - virtual int setBuffersUserDimensions(int w, int h); - virtual int setBuffersFormat(int format); - virtual int setScalingMode(int mode); - virtual int setBuffersTransform(int transform); - virtual int setBuffersTimestamp(int64_t timestamp); - virtual int setCrop(Rect const* rect); - virtual int setUsage(uint32_t reqUsage); - virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); - virtual int unlockAndPost(); - - enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS }; - enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; - -private: - void freeAllBuffers(); - int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; - - struct BufferSlot { - sp<GraphicBuffer> buffer; - Region dirtyRegion; - }; - - // mSurfaceTexture is the interface to the surface texture server. All - // operations on the surface texture client ultimately translate into - // interactions with the server using this interface. - // TODO: rename to mBufferProducer - sp<IGraphicBufferProducer> mSurfaceTexture; - - // mSlots stores the buffers that have been allocated for each buffer slot. - // It is initialized to null pointers, and gets filled in with the result of - // IGraphicBufferProducer::requestBuffer when the client dequeues a buffer from a - // slot that has not yet been used. The buffer allocated to a slot will also - // be replaced if the requested buffer usage or geometry differs from that - // of the buffer allocated to a slot. - BufferSlot mSlots[NUM_BUFFER_SLOTS]; - - // mReqWidth is the buffer width that will be requested at the next dequeue - // operation. It is initialized to 1. - uint32_t mReqWidth; - - // 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 - // deuque operation. It is initialized to PIXEL_FORMAT_RGBA_8888. - uint32_t mReqFormat; - - // mReqUsage is the set of buffer usage flags that will be requested - // at the next deuque operation. It is initialized to 0. - uint32_t mReqUsage; - - // mTimestamp is the timestamp that will be used for the next buffer queue - // operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that - // 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 buffers, regardless of the - // native_window_set_buffers_dimensions call. - uint32_t mDefaultWidth; - - // mDefaultHeight is default height of the buffers, regardless of the - // native_window_set_buffers_dimensions call. - uint32_t mDefaultHeight; - - // mUserWidth, if non-zero, is an application-specified override - // of mDefaultWidth. This is lower priority than the width set by - // native_window_set_buffers_dimensions. - uint32_t mUserWidth; - - // mUserHeight, if non-zero, is an application-specified override - // of mDefaultHeight. This is lower priority than the height set - // by native_window_set_buffers_dimensions. - uint32_t mUserHeight; - - // mTransformHint is the transform probably applied to buffers of this - // window. this is only a hint, actual transform may differ. - uint32_t mTransformHint; - - // mConsumerRunningBehind whether the consumer is running more than - // one buffer behind the producer. - mutable bool mConsumerRunningBehind; - - // mMutex is the mutex used to prevent concurrent access to the member - // variables of SurfaceTextureClient objects. It must be locked whenever the - // member variables are accessed. - mutable Mutex mMutex; - - // must be used from the lock/unlock thread - sp<GraphicBuffer> mLockedBuffer; - sp<GraphicBuffer> mPostedBuffer; - bool mConnectedToCpu; - - // must be accessed from lock/unlock thread only - Region mDirtyRegion; -}; - -}; // namespace android - -#endif // ANDROID_GUI_SURFACETEXTURECLIENT_H diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h index 5b400ca3ae..0798e170eb 100644 --- a/include/private/gui/LayerState.h +++ b/include/private/gui/LayerState.h @@ -51,7 +51,7 @@ struct layer_state_t { }; layer_state_t() - : surface(0), what(0), + : what(0), x(0), y(0), z(0), w(0), h(0), layerStack(0), alpha(0), flags(0), mask(0), reserved(0) @@ -70,7 +70,7 @@ struct layer_state_t { float dsdy; float dtdy; }; - SurfaceID surface; + sp<IBinder> surface; uint32_t what; float x; float y; diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h index f318cd899f..d3839ea076 100644 --- a/include/ui/GraphicBuffer.h +++ b/include/ui/GraphicBuffer.h @@ -124,7 +124,7 @@ private: friend class Surface; friend class BpSurface; friend class BnSurface; - friend class SurfaceTextureClient; + friend class Surface; friend class LightRefBase<GraphicBuffer>; GraphicBuffer(const GraphicBuffer& rhs); GraphicBuffer& operator = (const GraphicBuffer& rhs); diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk index d449298db6..994d3dbe31 100644 --- a/libs/binder/Android.mk +++ b/libs/binder/Android.mk @@ -14,8 +14,11 @@ # we have the common sources, plus some device-specific stuff sources := \ + AppOpsManager.cpp \ Binder.cpp \ BpBinder.cpp \ + IAppOpsCallback.cpp \ + IAppOpsService.cpp \ IInterface.cpp \ IMemory.cpp \ IPCThreadState.cpp \ diff --git a/libs/binder/AppOpsManager.cpp b/libs/binder/AppOpsManager.cpp new file mode 100644 index 0000000000..7ac1b11d56 --- /dev/null +++ b/libs/binder/AppOpsManager.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2013 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 <binder/AppOpsManager.h> +#include <binder/IServiceManager.h> + +#include <utils/SystemClock.h> + +namespace android { + +static String16 _appops("appops"); + +AppOpsManager::AppOpsManager() +{ +} + +sp<IAppOpsService> AppOpsManager::getService() +{ + int64_t startTime = 0; + mLock.lock(); + sp<IAppOpsService> service = mService; + while (service == NULL || !service->asBinder()->isBinderAlive()) { + sp<IBinder> binder = defaultServiceManager()->checkService(_appops); + if (binder == NULL) { + // Wait for the app ops service to come back... + if (startTime == 0) { + startTime = uptimeMillis(); + ALOGI("Waiting for app ops service"); + } else if ((uptimeMillis()-startTime) > 10000) { + ALOGW("Waiting too long for app ops service, giving up"); + return NULL; + } + sleep(1); + } else { + service = interface_cast<IAppOpsService>(binder); + mService = service; + } + } + mLock.unlock(); + return service; +} + +int32_t AppOpsManager::checkOp(int32_t op, int32_t uid, const String16& callingPackage) +{ + sp<IAppOpsService> service = getService(); + return service != NULL ? service->checkOperation(op, uid, callingPackage) : MODE_IGNORED; +} + +int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage) { + sp<IAppOpsService> service = getService(); + return service != NULL ? service->noteOperation(op, uid, callingPackage) : MODE_IGNORED; +} + +int32_t AppOpsManager::startOp(int32_t op, int32_t uid, const String16& callingPackage) { + sp<IAppOpsService> service = getService(); + return service != NULL ? service->startOperation(op, uid, callingPackage) : MODE_IGNORED; +} + +void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) { + sp<IAppOpsService> service = getService(); + if (service != NULL) { + service->finishOperation(op, uid, callingPackage); + } +} + +void AppOpsManager::startWatchingMode(int32_t op, const String16& packageName, + const sp<IAppOpsCallback>& callback) { + sp<IAppOpsService> service = getService(); + if (service != NULL) { + service->startWatchingMode(op, packageName, callback); + } +} + +void AppOpsManager::stopWatchingMode(const sp<IAppOpsCallback>& callback) { + sp<IAppOpsService> service = getService(); + if (service != NULL) { + service->stopWatchingMode(callback); + } +} + +}; // namespace android diff --git a/libs/binder/IAppOpsCallback.cpp b/libs/binder/IAppOpsCallback.cpp new file mode 100644 index 0000000000..e0aad2308d --- /dev/null +++ b/libs/binder/IAppOpsCallback.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2013 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 "AppOpsCallback" + +#include <binder/IAppOpsCallback.h> + +#include <utils/Debug.h> +#include <utils/Log.h> +#include <binder/Parcel.h> +#include <utils/String8.h> + +#include <private/binder/Static.h> + +namespace android { + +// ---------------------------------------------------------------------- + +class BpAppOpsCallback : public BpInterface<IAppOpsCallback> +{ +public: + BpAppOpsCallback(const sp<IBinder>& impl) + : BpInterface<IAppOpsCallback>(impl) + { + } + + virtual void opChanged(int32_t op, const String16& packageName) { + Parcel data, reply; + data.writeInterfaceToken(IAppOpsCallback::getInterfaceDescriptor()); + data.writeInt32(op); + data.writeString16(packageName); + remote()->transact(OP_CHANGED_TRANSACTION, data, &reply); + } +}; + +IMPLEMENT_META_INTERFACE(AppOpsCallback, "com.android.internal.app.IAppOpsCallback"); + +// ---------------------------------------------------------------------- + +status_t BnAppOpsCallback::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch(code) { + case OP_CHANGED_TRANSACTION: { + CHECK_INTERFACE(IAppOpsCallback, data, reply); + int32_t op = data.readInt32(); + String16 packageName = data.readString16(); + opChanged(op, packageName); + reply->writeNoException(); + return NO_ERROR; + } break; + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +}; // namespace android diff --git a/libs/binder/IAppOpsService.cpp b/libs/binder/IAppOpsService.cpp new file mode 100644 index 0000000000..282b30fedd --- /dev/null +++ b/libs/binder/IAppOpsService.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2013 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 "AppOpsService" + +#include <binder/IAppOpsService.h> + +#include <utils/Debug.h> +#include <utils/Log.h> +#include <binder/Parcel.h> +#include <utils/String8.h> + +#include <private/binder/Static.h> + +namespace android { + +// ---------------------------------------------------------------------- + +class BpAppOpsService : public BpInterface<IAppOpsService> +{ +public: + BpAppOpsService(const sp<IBinder>& impl) + : BpInterface<IAppOpsService>(impl) + { + } + + virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) { + Parcel data, reply; + data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); + data.writeInt32(code); + data.writeInt32(uid); + data.writeString16(packageName); + remote()->transact(CHECK_OPERATION_TRANSACTION, data, &reply); + // fail on exception + if (reply.readExceptionCode() != 0) return MODE_ERRORED; + return reply.readInt32(); + } + + virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName) { + Parcel data, reply; + data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); + data.writeInt32(code); + data.writeInt32(uid); + data.writeString16(packageName); + remote()->transact(NOTE_OPERATION_TRANSACTION, data, &reply); + // fail on exception + if (reply.readExceptionCode() != 0) return MODE_ERRORED; + return reply.readInt32(); + } + + virtual int32_t startOperation(int32_t code, int32_t uid, const String16& packageName) { + Parcel data, reply; + data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); + data.writeInt32(code); + data.writeInt32(uid); + data.writeString16(packageName); + remote()->transact(START_OPERATION_TRANSACTION, data, &reply); + // fail on exception + if (reply.readExceptionCode() != 0) return MODE_ERRORED; + return reply.readInt32(); + } + + virtual void finishOperation(int32_t code, int32_t uid, const String16& packageName) { + Parcel data, reply; + data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); + data.writeInt32(code); + data.writeInt32(uid); + data.writeString16(packageName); + remote()->transact(FINISH_OPERATION_TRANSACTION, data, &reply); + } + + virtual void startWatchingMode(int32_t op, const String16& packageName, + const sp<IAppOpsCallback>& callback) { + Parcel data, reply; + data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); + data.writeInt32(op); + data.writeString16(packageName); + data.writeStrongBinder(callback->asBinder()); + remote()->transact(START_WATCHING_MODE_TRANSACTION, data, &reply); + } + + virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) { + Parcel data, reply; + data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); + data.writeStrongBinder(callback->asBinder()); + remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply); + } +}; + +IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService"); + +// ---------------------------------------------------------------------- + +status_t BnAppOpsService::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + //printf("AppOpsService received: "); data.print(); + switch(code) { + case CHECK_OPERATION_TRANSACTION: { + CHECK_INTERFACE(IAppOpsService, data, reply); + int32_t code = data.readInt32(); + int32_t uid = data.readInt32(); + String16 packageName = data.readString16(); + int32_t res = checkOperation(code, uid, packageName); + reply->writeNoException(); + reply->writeInt32(res); + return NO_ERROR; + } break; + case NOTE_OPERATION_TRANSACTION: { + CHECK_INTERFACE(IAppOpsService, data, reply); + int32_t code = data.readInt32(); + int32_t uid = data.readInt32(); + String16 packageName = data.readString16(); + int32_t res = noteOperation(code, uid, packageName); + reply->writeNoException(); + reply->writeInt32(res); + return NO_ERROR; + } break; + case START_OPERATION_TRANSACTION: { + CHECK_INTERFACE(IAppOpsService, data, reply); + int32_t code = data.readInt32(); + int32_t uid = data.readInt32(); + String16 packageName = data.readString16(); + int32_t res = startOperation(code, uid, packageName); + reply->writeNoException(); + reply->writeInt32(res); + return NO_ERROR; + } break; + case FINISH_OPERATION_TRANSACTION: { + CHECK_INTERFACE(IAppOpsService, data, reply); + int32_t code = data.readInt32(); + int32_t uid = data.readInt32(); + String16 packageName = data.readString16(); + finishOperation(code, uid, packageName); + reply->writeNoException(); + return NO_ERROR; + } break; + case START_WATCHING_MODE_TRANSACTION: { + CHECK_INTERFACE(IAppOpsService, data, reply); + int32_t op = data.readInt32(); + String16 packageName = data.readString16(); + sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder()); + startWatchingMode(op, packageName, callback); + reply->writeNoException(); + return NO_ERROR; + } break; + case STOP_WATCHING_MODE_TRANSACTION: { + CHECK_INTERFACE(IAppOpsService, data, reply); + sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder()); + stopWatchingMode(callback); + reply->writeNoException(); + return NO_ERROR; + } break; + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +}; // namespace android diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk index b1aeb32889..544b66407e 100644 --- a/libs/gui/Android.mk +++ b/libs/gui/Android.mk @@ -25,8 +25,8 @@ LOCAL_SRC_FILES:= \ SensorEventQueue.cpp \ SensorManager.cpp \ Surface.cpp \ + SurfaceControl.cpp \ SurfaceComposerClient.cpp \ - SurfaceTextureClient.cpp \ LOCAL_SHARED_LIBRARIES := \ libbinder \ diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp index 50798836c6..885b4e497f 100644 --- a/libs/gui/BufferItemConsumer.cpp +++ b/libs/gui/BufferItemConsumer.cpp @@ -62,7 +62,7 @@ status_t BufferItemConsumer::acquireBuffer(BufferItem *item, bool waitForFence) return err; } - if (waitForFence && item->mFence.get()) { + if (waitForFence) { err = item->mFence->waitForever(1000, "BufferItemConsumer::acquireBuffer"); if (err != OK) { BI_LOGE("Failed to wait for fence of acquired buffer: %s (%d)", diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index 4be655b3f8..d93c067176 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -372,8 +372,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence, h = mDefaultHeight; } - // buffer is now in DEQUEUED (but can also be current at the same time, - // if we're in synchronous mode) mSlots[buf].mBufferState = BufferSlot::DEQUEUED; const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); @@ -387,7 +385,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence, mSlots[buf].mGraphicBuffer = NULL; mSlots[buf].mRequestBufferCalled = false; mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; - mSlots[buf].mFence.clear(); + mSlots[buf].mFence = Fence::NO_FENCE; mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; returnFlags |= IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION; @@ -397,7 +395,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence, eglFence = mSlots[buf].mEglFence; outFence = mSlots[buf].mFence; mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; - mSlots[buf].mFence.clear(); + mSlots[buf].mFence = Fence::NO_FENCE; } // end lock scope if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) { @@ -423,7 +421,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence, } } - if (eglFence != EGL_NO_SYNC_KHR) { EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000); // If something goes wrong, log the error, but return the buffer without @@ -488,6 +485,11 @@ status_t BufferQueue::queueBuffer(int buf, input.deflate(×tamp, &crop, &scalingMode, &transform, &fence); + if (fence == NULL) { + ST_LOGE("queueBuffer: fence is NULL"); + return BAD_VALUE; + } + ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x " "scale=%s", buf, timestamp, crop.left, crop.top, crop.right, crop.bottom, @@ -607,6 +609,9 @@ void BufferQueue::cancelBuffer(int buf, sp<Fence> fence) { ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", buf, mSlots[buf].mBufferState); return; + } else if (fence == NULL) { + ST_LOGE("cancelBuffer: fence is NULL"); + return; } mSlots[buf].mBufferState = BufferSlot::FREE; mSlots[buf].mFrameNumber = 0; @@ -785,7 +790,7 @@ void BufferQueue::freeBufferLocked(int slot) { eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence); mSlots[slot].mEglFence = EGL_NO_SYNC_KHR; } - mSlots[slot].mFence.clear(); + mSlots[slot].mFence = Fence::NO_FENCE; } void BufferQueue::freeAllBuffersLocked() { @@ -843,7 +848,7 @@ status_t BufferQueue::acquireBuffer(BufferItem *buffer) { mSlots[buf].mAcquireCalled = true; mSlots[buf].mNeedsCleanupOnRelease = false; mSlots[buf].mBufferState = BufferSlot::ACQUIRED; - mSlots[buf].mFence.clear(); + mSlots[buf].mFence = Fence::NO_FENCE; mQueue.erase(front); mDequeueCondition.broadcast(); @@ -863,8 +868,8 @@ status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display, Mutex::Autolock _l(mMutex); - if (buf == INVALID_BUFFER_SLOT) { - return -EINVAL; + if (buf == INVALID_BUFFER_SLOT || fence == NULL) { + return BAD_VALUE; } mSlots[buf].mEglDisplay = display; diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index 8f391aa495..fb6ba7dbff 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -84,7 +84,7 @@ ConsumerBase::~ConsumerBase() { void ConsumerBase::freeBufferLocked(int slotIndex) { CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); mSlots[slotIndex].mGraphicBuffer = 0; - mSlots[slotIndex].mFence = 0; + mSlots[slotIndex].mFence = Fence::NO_FENCE; } // Used for refactoring, should not be in final interface @@ -228,7 +228,7 @@ status_t ConsumerBase::releaseBufferLocked(int slot, EGLDisplay display, freeBufferLocked(slot); } - mSlots[slot].mFence.clear(); + mSlots[slot].mFence = Fence::NO_FENCE; return err; } diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index ba23f9edf8..09831fb8b9 100644 --- a/libs/gui/GLConsumer.cpp +++ b/libs/gui/GLConsumer.cpp @@ -117,6 +117,7 @@ GLConsumer::GLConsumer(GLuint tex, bool allowSynchronousMode, GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) : ConsumerBase(bufferQueue == 0 ? new BufferQueue(allowSynchronousMode) : bufferQueue), mCurrentTransform(0), + mCurrentFence(Fence::NO_FENCE), mCurrentTimestamp(0), mFilteringEnabled(true), mTexName(tex), @@ -823,7 +824,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const { return INVALID_OPERATION; } - if (mCurrentFence != NULL) { + if (mCurrentFence->isValid()) { if (useWaitSync) { // Create an EGLSyncKHR from the current fence. int fenceFd = mCurrentFence->dup(); diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index c949817036..54860d794c 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -94,9 +94,11 @@ public: return result; } *buf = reply.readInt32(); - fence.clear(); - bool hasFence = reply.readInt32(); - if (hasFence) { + bool fenceWasWritten = reply.readInt32(); + if (fenceWasWritten) { + // If the fence was written by the callee, then overwrite the + // caller's fence here. If it wasn't written then don't touch the + // caller's fence. fence = new Fence(); reply.read(*fence.get()); } @@ -121,13 +123,9 @@ public: virtual void cancelBuffer(int buf, sp<Fence> fence) { Parcel data, reply; - bool hasFence = fence.get() && fence->isValid(); data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeInt32(buf); - data.writeInt32(hasFence); - if (hasFence) { - data.write(*fence.get()); - } + data.write(*fence.get()); remote()->transact(CANCEL_BUFFER, data, &reply); } @@ -218,10 +216,9 @@ status_t BnGraphicBufferProducer::onTransact( int buf; sp<Fence> fence; int result = dequeueBuffer(&buf, fence, w, h, format, usage); - bool hasFence = fence.get() && fence->isValid(); reply->writeInt32(buf); - reply->writeInt32(hasFence); - if (hasFence) { + reply->writeInt32(fence != NULL); + if (fence != NULL) { reply->write(*fence.get()); } reply->writeInt32(result); @@ -241,12 +238,8 @@ status_t BnGraphicBufferProducer::onTransact( case CANCEL_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int buf = data.readInt32(); - sp<Fence> fence; - bool hasFence = data.readInt32(); - if (hasFence) { - fence = new Fence(); - data.read(*fence.get()); - } + sp<Fence> fence = new Fence(); + data.read(*fence.get()); cancelBuffer(buf, fence); return NO_ERROR; } break; @@ -289,10 +282,6 @@ status_t BnGraphicBufferProducer::onTransact( // ---------------------------------------------------------------------------- -static bool isValid(const sp<Fence>& fence) { - return fence.get() && fence->isValid(); -} - IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) { parcel.read(*this); } @@ -303,29 +292,24 @@ size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const + sizeof(crop) + sizeof(scalingMode) + sizeof(transform) - + sizeof(bool) - + (isValid(fence) ? fence->getFlattenedSize() : 0); + + fence->getFlattenedSize(); } size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const { - return isValid(fence) ? fence->getFdCount() : 0; + return fence->getFdCount(); } status_t IGraphicBufferProducer::QueueBufferInput::flatten(void* buffer, size_t size, int fds[], size_t count) const { status_t err = NO_ERROR; - bool haveFence = isValid(fence); char* p = (char*)buffer; memcpy(p, ×tamp, sizeof(timestamp)); p += sizeof(timestamp); memcpy(p, &crop, sizeof(crop)); p += sizeof(crop); memcpy(p, &scalingMode, sizeof(scalingMode)); p += sizeof(scalingMode); memcpy(p, &transform, sizeof(transform)); p += sizeof(transform); - memcpy(p, &haveFence, sizeof(haveFence)); p += sizeof(haveFence); - if (haveFence) { - err = fence->flatten(p, size - (p - (char*)buffer), fds, count); - } + err = fence->flatten(p, size - (p - (char*)buffer), fds, count); return err; } @@ -333,17 +317,13 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(void const* buffer, size_t size, int fds[], size_t count) { status_t err = NO_ERROR; - bool haveFence; const char* p = (const char*)buffer; memcpy(×tamp, p, sizeof(timestamp)); p += sizeof(timestamp); memcpy(&crop, p, sizeof(crop)); p += sizeof(crop); memcpy(&scalingMode, p, sizeof(scalingMode)); p += sizeof(scalingMode); memcpy(&transform, p, sizeof(transform)); p += sizeof(transform); - memcpy(&haveFence, p, sizeof(haveFence)); p += sizeof(haveFence); - if (haveFence) { - fence = new Fence(); - err = fence->unflatten(p, size - (p - (const char*)buffer), fds, count); - } + fence = new Fence(); + err = fence->unflatten(p, size - (p - (const char*)buffer), fds, count); return err; } diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp index 8f7bc052cd..101292d945 100644 --- a/libs/gui/ISurfaceComposerClient.cpp +++ b/libs/gui/ISurfaceComposerClient.cpp @@ -50,8 +50,7 @@ public: { } - virtual sp<ISurface> createSurface( surface_data_t* params, - const String8& name, + virtual sp<ISurface> createSurface( const String8& name, uint32_t w, uint32_t h, PixelFormat format, @@ -65,15 +64,14 @@ public: data.writeInt32(format); data.writeInt32(flags); remote()->transact(CREATE_SURFACE, data, &reply); - params->readFromParcel(reply); return interface_cast<ISurface>(reply.readStrongBinder()); } - virtual status_t destroySurface(SurfaceID sid) + virtual status_t destroySurface(const sp<IBinder>& handle) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor()); - data.writeInt32(sid); + data.writeStrongBinder(handle); remote()->transact(DESTROY_SURFACE, data, &reply); return reply.readInt32(); } @@ -89,21 +87,18 @@ status_t BnSurfaceComposerClient::onTransact( switch(code) { case CREATE_SURFACE: { CHECK_INTERFACE(ISurfaceComposerClient, data, reply); - surface_data_t params; String8 name = data.readString8(); uint32_t w = data.readInt32(); uint32_t h = data.readInt32(); PixelFormat format = data.readInt32(); uint32_t flags = data.readInt32(); - sp<ISurface> s = createSurface(¶ms, name, w, h, - format, flags); - params.writeToParcel(reply); + sp<ISurface> s = createSurface(name, w, h, format, flags); reply->writeStrongBinder(s->asBinder()); return NO_ERROR; } break; case DESTROY_SURFACE: { CHECK_INTERFACE(ISurfaceComposerClient, data, reply); - reply->writeInt32( destroySurface( data.readInt32() ) ); + reply->writeInt32( destroySurface( data.readStrongBinder() ) ); return NO_ERROR; } break; default: @@ -111,20 +106,4 @@ status_t BnSurfaceComposerClient::onTransact( } } -// ---------------------------------------------------------------------- - -status_t ISurfaceComposerClient::surface_data_t::readFromParcel(const Parcel& parcel) -{ - token = parcel.readInt32(); - identity = parcel.readInt32(); - return NO_ERROR; -} - -status_t ISurfaceComposerClient::surface_data_t::writeToParcel(Parcel* parcel) const -{ - parcel->writeInt32(token); - parcel->writeInt32(identity); - return NO_ERROR; -} - }; // namespace android diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 5e5edcd2db..acdbd77161 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -24,29 +24,41 @@ namespace android { status_t layer_state_t::write(Parcel& output) const { - status_t err; - - err = output.write(transparentRegion); - if (err < NO_ERROR) return err; - - // NOTE: regions are at the end of the structure - size_t size = sizeof(layer_state_t); - size -= sizeof(transparentRegion); - err = output.write(this, size); - return err; + output.writeStrongBinder(surface); + output.writeInt32(what); + output.writeFloat(x); + output.writeFloat(y); + output.writeInt32(z); + output.writeInt32(w); + output.writeInt32(h); + output.writeInt32(layerStack); + output.writeFloat(alpha); + output.writeInt32(flags); + output.writeInt32(mask); + *reinterpret_cast<layer_state_t::matrix22_t *>( + output.writeInplace(sizeof(layer_state_t::matrix22_t))) = matrix; + output.write(crop); + output.write(transparentRegion); + return NO_ERROR; } status_t layer_state_t::read(const Parcel& input) { - status_t err; - - err = input.read(transparentRegion); - if (err < NO_ERROR) return err; - - // NOTE: regions are at the end of the structure - size_t size = sizeof(layer_state_t); - size -= sizeof(transparentRegion); - input.read(this, size); + surface = input.readStrongBinder(); + what = input.readInt32(); + x = input.readFloat(); + y = input.readFloat(); + z = input.readInt32(); + w = input.readInt32(); + h = input.readInt32(); + layerStack = input.readInt32(); + alpha = input.readFloat(); + flags = input.readInt32(); + mask = input.readInt32(); + matrix = *reinterpret_cast<layer_state_t::matrix22_t const *>( + input.readInplace(sizeof(layer_state_t::matrix22_t))); + input.read(crop); + input.read(transparentRegion); return NO_ERROR; } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 51d37b3cf7..410ad5da92 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * 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. @@ -15,371 +15,851 @@ */ #define LOG_TAG "Surface" - -#include <stdint.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> +#define ATRACE_TAG ATRACE_TAG_GRAPHICS +//#define LOG_NDEBUG 0 #include <android/native_window.h> -#include <utils/CallStack.h> -#include <utils/Errors.h> -#include <utils/Log.h> -#include <utils/threads.h> +#include <binder/Parcel.h> -#include <binder/IPCThreadState.h> +#include <utils/Log.h> +#include <utils/Trace.h> -#include <ui/DisplayInfo.h> -#include <ui/GraphicBuffer.h> -#include <ui/Rect.h> +#include <ui/Fence.h> -#include <gui/ISurface.h> #include <gui/ISurfaceComposer.h> -#include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> -#include <gui/SurfaceTextureClient.h> +#include <gui/GLConsumer.h> +#include <gui/Surface.h> -namespace android { +#include <private/gui/ComposerService.h> -// ============================================================================ -// SurfaceControl -// ============================================================================ +namespace android { -SurfaceControl::SurfaceControl( - const sp<SurfaceComposerClient>& client, - const sp<ISurface>& surface, - const ISurfaceComposerClient::surface_data_t& data) - : mClient(client), mSurface(surface), - mToken(data.token), mIdentity(data.identity) +Surface::Surface( + const sp<IGraphicBufferProducer>& bufferProducer) { + Surface::init(); + Surface::setIGraphicBufferProducer(bufferProducer); } - -SurfaceControl::~SurfaceControl() -{ - destroy(); + +Surface::Surface() { + Surface::init(); } -void SurfaceControl::destroy() -{ - if (isValid()) { - mClient->destroySurface(mToken); +Surface::~Surface() { + if (mConnectedToCpu) { + Surface::disconnect(NATIVE_WINDOW_API_CPU); } - - // 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(); - IPCThreadState::self()->flushCommands(); } -void SurfaceControl::clear() +void Surface::init() { + // Initialize the ANativeWindow function pointers. + ANativeWindow::setSwapInterval = hook_setSwapInterval; + ANativeWindow::dequeueBuffer = hook_dequeueBuffer; + ANativeWindow::cancelBuffer = hook_cancelBuffer; + ANativeWindow::queueBuffer = hook_queueBuffer; + ANativeWindow::query = hook_query; + ANativeWindow::perform = hook_perform; + + ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED; + ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED; + ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED; + ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED; + + const_cast<int&>(ANativeWindow::minSwapInterval) = 0; + const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; + + mReqWidth = 0; + mReqHeight = 0; + mReqFormat = 0; + mReqUsage = 0; + mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; + mCrop.clear(); + mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; + mTransform = 0; + mDefaultWidth = 0; + mDefaultHeight = 0; + mUserWidth = 0; + mUserHeight = 0; + mTransformHint = 0; + mConsumerRunningBehind = false; + mConnectedToCpu = false; +} + +void Surface::setIGraphicBufferProducer( + const sp<IGraphicBufferProducer>& bufferProducer) { - // here, the window manager tells us explicitly that we should destroy - // the surface's resource. Soon after this call, it will also release - // its last reference (which will call the dtor); however, it is possible - // that a client living in the same process still holds references which - // would delay the call to the dtor -- that is why we need this explicit - // "clear()" call. - destroy(); + mGraphicBufferProducer = bufferProducer; } -bool SurfaceControl::isSameSurface( - const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) -{ - if (lhs == 0 || rhs == 0) - return false; - return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); -} - -status_t SurfaceControl::setLayerStack(int32_t layerStack) { - status_t err = validate(); - if (err < 0) return err; - const sp<SurfaceComposerClient>& client(mClient); - return client->setLayerStack(mToken, 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(mToken, 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(mToken, 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(mToken, w, h); -} -status_t SurfaceControl::hide() { - status_t err = validate(); - if (err < 0) return err; - const sp<SurfaceComposerClient>& client(mClient); - return client->hide(mToken); -} -status_t SurfaceControl::show() { - status_t err = validate(); - if (err < 0) return err; - const sp<SurfaceComposerClient>& client(mClient); - return client->show(mToken); -} -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(mToken, 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(mToken, transparent); -} -status_t SurfaceControl::setAlpha(float alpha) { - status_t err = validate(); - if (err < 0) return err; - const sp<SurfaceComposerClient>& client(mClient); - return client->setAlpha(mToken, 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(mToken, 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(mToken, crop); -} - -status_t SurfaceControl::validate() const -{ - if (mToken<0 || mClient==0) { - ALOGE("invalid token (%d, identity=%u) or client (%p)", - mToken, mIdentity, mClient.get()); - return NO_INIT; +sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const { + return mGraphicBufferProducer; +} + +int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) { + Surface* c = getSelf(window); + return c->setSwapInterval(interval); +} + +int Surface::hook_dequeueBuffer(ANativeWindow* window, + ANativeWindowBuffer** buffer, int* fenceFd) { + Surface* c = getSelf(window); + return c->dequeueBuffer(buffer, fenceFd); +} + +int Surface::hook_cancelBuffer(ANativeWindow* window, + ANativeWindowBuffer* buffer, int fenceFd) { + Surface* c = getSelf(window); + return c->cancelBuffer(buffer, fenceFd); +} + +int Surface::hook_queueBuffer(ANativeWindow* window, + ANativeWindowBuffer* buffer, int fenceFd) { + Surface* c = getSelf(window); + return c->queueBuffer(buffer, fenceFd); +} + +int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer** buffer) { + Surface* c = getSelf(window); + ANativeWindowBuffer* buf; + int fenceFd = -1; + int result = c->dequeueBuffer(&buf, &fenceFd); + sp<Fence> fence(new Fence(fenceFd)); + int waitResult = fence->waitForever(1000, "dequeueBuffer_DEPRECATED"); + if (waitResult != OK) { + ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d", + waitResult); + c->cancelBuffer(buf, -1); + return waitResult; } - return NO_ERROR; + *buffer = buf; + return result; } -status_t SurfaceControl::writeSurfaceToParcel( - const sp<SurfaceControl>& control, Parcel* parcel) -{ - sp<ISurface> sur; - uint32_t identity = 0; - if (SurfaceControl::isValid(control)) { - sur = control->mSurface; - identity = control->mIdentity; +int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer) { + Surface* c = getSelf(window); + return c->cancelBuffer(buffer, -1); +} + +int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer) { + Surface* c = getSelf(window); + return c->lockBuffer_DEPRECATED(buffer); +} + +int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer) { + Surface* c = getSelf(window); + return c->queueBuffer(buffer, -1); +} + +int Surface::hook_query(const ANativeWindow* window, + int what, int* value) { + const Surface* c = getSelf(window); + return c->query(what, value); +} + +int Surface::hook_perform(ANativeWindow* window, int operation, ...) { + va_list args; + va_start(args, operation); + Surface* c = getSelf(window); + return c->perform(operation, args); +} + +int Surface::setSwapInterval(int interval) { + ATRACE_CALL(); + // EGL specification states: + // interval is silently clamped to minimum and maximum implementation + // dependent values before being stored. + // Although we don't have to, we apply the same logic here. + + if (interval < minSwapInterval) + interval = minSwapInterval; + + if (interval > maxSwapInterval) + interval = maxSwapInterval; + + status_t res = mGraphicBufferProducer->setSynchronousMode(interval ? true : false); + + return res; +} + +int Surface::dequeueBuffer(android_native_buffer_t** buffer, + int* fenceFd) { + ATRACE_CALL(); + ALOGV("Surface::dequeueBuffer"); + Mutex::Autolock lock(mMutex); + int buf = -1; + int reqW = mReqWidth ? mReqWidth : mUserWidth; + int reqH = mReqHeight ? mReqHeight : mUserHeight; + sp<Fence> fence; + status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, fence, reqW, reqH, + mReqFormat, mReqUsage); + if (result < 0) { + ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d)" + "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage, + result); + return result; } - parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); - parcel->writeStrongBinder(NULL); // NULL IGraphicBufferProducer in this case. - parcel->writeInt32(identity); - return NO_ERROR; + sp<GraphicBuffer>& gbuf(mSlots[buf].buffer); + if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) { + freeAllBuffers(); + } + + if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) { + result = mGraphicBufferProducer->requestBuffer(buf, &gbuf); + if (result != NO_ERROR) { + ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", + result); + return result; + } + } + + if (fence->isValid()) { + *fenceFd = fence->dup(); + if (*fenceFd == -1) { + ALOGE("dequeueBuffer: error duping fence: %d", errno); + // dup() should never fail; something is badly wrong. Soldier on + // and hope for the best; the worst that should happen is some + // visible corruption that lasts until the next frame. + } + } else { + *fenceFd = -1; + } + + *buffer = gbuf.get(); + return OK; } -sp<Surface> SurfaceControl::getSurface() const -{ - Mutex::Autolock _l(mLock); - if (mSurfaceData == 0) { - sp<SurfaceControl> surface_control(const_cast<SurfaceControl*>(this)); - mSurfaceData = new Surface(surface_control); +int Surface::cancelBuffer(android_native_buffer_t* buffer, + int fenceFd) { + ATRACE_CALL(); + ALOGV("Surface::cancelBuffer"); + Mutex::Autolock lock(mMutex); + int i = getSlotFromBufferLocked(buffer); + if (i < 0) { + return i; + } + sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); + mGraphicBufferProducer->cancelBuffer(i, fence); + return OK; +} + +int Surface::getSlotFromBufferLocked( + android_native_buffer_t* buffer) const { + bool dumpedState = false; + for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { + if (mSlots[i].buffer != NULL && + mSlots[i].buffer->handle == buffer->handle) { + return i; + } } - return mSurfaceData; + ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle); + return BAD_VALUE; } -// ============================================================================ -// Surface -// ============================================================================ +int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer) { + ALOGV("Surface::lockBuffer"); + Mutex::Autolock lock(mMutex); + return OK; +} -// --------------------------------------------------------------------------- +int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { + ATRACE_CALL(); + ALOGV("Surface::queueBuffer"); + Mutex::Autolock lock(mMutex); + int64_t timestamp; + if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) { + timestamp = systemTime(SYSTEM_TIME_MONOTONIC); + ALOGV("Surface::queueBuffer making up timestamp: %.2f ms", + timestamp / 1000000.f); + } else { + timestamp = mTimestamp; + } + int i = getSlotFromBufferLocked(buffer); + if (i < 0) { + return i; + } -Surface::Surface(const sp<SurfaceControl>& surface) - : SurfaceTextureClient(), - mSurface(surface->mSurface), - mIdentity(surface->mIdentity) -{ - sp<IGraphicBufferProducer> st; - if (mSurface != NULL) { - st = mSurface->getSurfaceTexture(); + + // Make sure the crop rectangle is entirely inside the buffer. + Rect crop; + mCrop.intersect(Rect(buffer->width, buffer->height), &crop); + + sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); + IGraphicBufferProducer::QueueBufferOutput output; + IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode, + mTransform, fence); + status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output); + if (err != OK) { + ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err); } - init(st); + uint32_t numPendingBuffers = 0; + output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, + &numPendingBuffers); + + mConsumerRunningBehind = (numPendingBuffers >= 2); + + return err; } -Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref) - : SurfaceTextureClient() +int Surface::query(int what, int* value) const { + ATRACE_CALL(); + ALOGV("Surface::query"); + { // scope for the lock + Mutex::Autolock lock(mMutex); + switch (what) { + case NATIVE_WINDOW_FORMAT: + if (mReqFormat) { + *value = mReqFormat; + return NO_ERROR; + } + break; + case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: { + sp<ISurfaceComposer> composer( + ComposerService::getComposerService()); + if (composer->authenticateSurfaceTexture(mGraphicBufferProducer)) { + *value = 1; + } else { + *value = 0; + } + return NO_ERROR; + } + case NATIVE_WINDOW_CONCRETE_TYPE: + *value = NATIVE_WINDOW_SURFACE; + return NO_ERROR; + case NATIVE_WINDOW_DEFAULT_WIDTH: + *value = mUserWidth ? mUserWidth : mDefaultWidth; + return NO_ERROR; + case NATIVE_WINDOW_DEFAULT_HEIGHT: + *value = mUserHeight ? mUserHeight : mDefaultHeight; + return NO_ERROR; + case NATIVE_WINDOW_TRANSFORM_HINT: + *value = mTransformHint; + return NO_ERROR; + case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: { + status_t err = NO_ERROR; + if (!mConsumerRunningBehind) { + *value = 0; + } else { + err = mGraphicBufferProducer->query(what, value); + if (err == NO_ERROR) { + mConsumerRunningBehind = *value; + } + } + return err; + } + } + } + return mGraphicBufferProducer->query(what, value); +} + +int Surface::perform(int operation, va_list args) { - mSurface = interface_cast<ISurface>(ref); - sp<IBinder> st_binder(parcel.readStrongBinder()); - sp<IGraphicBufferProducer> st; - if (st_binder != NULL) { - st = interface_cast<IGraphicBufferProducer>(st_binder); - } else if (mSurface != NULL) { - st = mSurface->getSurfaceTexture(); + int res = NO_ERROR; + switch (operation) { + case NATIVE_WINDOW_CONNECT: + // deprecated. must return NO_ERROR. + break; + case NATIVE_WINDOW_DISCONNECT: + // deprecated. must return NO_ERROR. + break; + case NATIVE_WINDOW_SET_USAGE: + res = dispatchSetUsage(args); + break; + case NATIVE_WINDOW_SET_CROP: + res = dispatchSetCrop(args); + break; + case NATIVE_WINDOW_SET_BUFFER_COUNT: + res = dispatchSetBufferCount(args); + break; + case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: + res = dispatchSetBuffersGeometry(args); + break; + case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: + res = dispatchSetBuffersTransform(args); + break; + case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: + res = dispatchSetBuffersTimestamp(args); + break; + case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: + res = dispatchSetBuffersDimensions(args); + break; + case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS: + res = dispatchSetBuffersUserDimensions(args); + break; + case NATIVE_WINDOW_SET_BUFFERS_FORMAT: + res = dispatchSetBuffersFormat(args); + break; + case NATIVE_WINDOW_LOCK: + res = dispatchLock(args); + break; + case NATIVE_WINDOW_UNLOCK_AND_POST: + res = dispatchUnlockAndPost(args); + break; + case NATIVE_WINDOW_SET_SCALING_MODE: + res = dispatchSetScalingMode(args); + break; + case NATIVE_WINDOW_API_CONNECT: + res = dispatchConnect(args); + break; + case NATIVE_WINDOW_API_DISCONNECT: + res = dispatchDisconnect(args); + break; + default: + res = NAME_NOT_FOUND; + break; } + return res; +} - mIdentity = parcel.readInt32(); - init(st); +int Surface::dispatchConnect(va_list args) { + int api = va_arg(args, int); + return connect(api); } -Surface::Surface(const sp<IGraphicBufferProducer>& st) - : SurfaceTextureClient(), - mSurface(NULL), - mIdentity(0) -{ - init(st); +int Surface::dispatchDisconnect(va_list args) { + int api = va_arg(args, int); + return disconnect(api); } -status_t Surface::writeToParcel( - const sp<Surface>& surface, Parcel* parcel) -{ - sp<ISurface> sur; - sp<IGraphicBufferProducer> st; - uint32_t identity = 0; - if (Surface::isValid(surface)) { - sur = surface->mSurface; - st = surface->getISurfaceTexture(); - identity = surface->mIdentity; - } else if (surface != 0 && - (surface->mSurface != NULL || - surface->getISurfaceTexture() != NULL)) { - ALOGE("Parceling invalid surface with non-NULL ISurface/IGraphicBufferProducer " - "as NULL: mSurface = %p, bufferProducer = %p, mIdentity = %d, ", - surface->mSurface.get(), surface->getISurfaceTexture().get(), - surface->mIdentity); +int Surface::dispatchSetUsage(va_list args) { + int usage = va_arg(args, int); + return setUsage(usage); +} + +int Surface::dispatchSetCrop(va_list args) { + android_native_rect_t const* rect = va_arg(args, android_native_rect_t*); + return setCrop(reinterpret_cast<Rect const*>(rect)); +} + +int Surface::dispatchSetBufferCount(va_list args) { + size_t bufferCount = va_arg(args, size_t); + return setBufferCount(bufferCount); +} + +int Surface::dispatchSetBuffersGeometry(va_list args) { + int w = va_arg(args, int); + int h = va_arg(args, int); + int f = va_arg(args, int); + int err = setBuffersDimensions(w, h); + if (err != 0) { + return err; } + return setBuffersFormat(f); +} - parcel->writeStrongBinder(sur != NULL ? sur->asBinder() : NULL); - parcel->writeStrongBinder(st != NULL ? st->asBinder() : NULL); - parcel->writeInt32(identity); - return NO_ERROR; +int Surface::dispatchSetBuffersDimensions(va_list args) { + int w = va_arg(args, int); + int h = va_arg(args, int); + return setBuffersDimensions(w, h); +} +int Surface::dispatchSetBuffersUserDimensions(va_list args) { + int w = va_arg(args, int); + int h = va_arg(args, int); + return setBuffersUserDimensions(w, h); } -Mutex Surface::sCachedSurfacesLock; -DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces; +int Surface::dispatchSetBuffersFormat(va_list args) { + int f = va_arg(args, int); + return setBuffersFormat(f); +} -sp<Surface> Surface::readFromParcel(const Parcel& data) { - Mutex::Autolock _l(sCachedSurfacesLock); - sp<IBinder> binder(data.readStrongBinder()); - sp<Surface> surface = sCachedSurfaces.valueFor(binder).promote(); - if (surface == 0) { - surface = new Surface(data, binder); - sCachedSurfaces.add(binder, surface); - } else { - // The Surface was found in the cache, but we still should clear any - // remaining data from the parcel. - data.readStrongBinder(); // IGraphicBufferProducer - data.readInt32(); // identity +int Surface::dispatchSetScalingMode(va_list args) { + int m = va_arg(args, int); + return setScalingMode(m); +} + +int Surface::dispatchSetBuffersTransform(va_list args) { + int transform = va_arg(args, int); + return setBuffersTransform(transform); +} + +int Surface::dispatchSetBuffersTimestamp(va_list args) { + int64_t timestamp = va_arg(args, int64_t); + return setBuffersTimestamp(timestamp); +} + +int Surface::dispatchLock(va_list args) { + ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*); + ARect* inOutDirtyBounds = va_arg(args, ARect*); + return lock(outBuffer, inOutDirtyBounds); +} + +int Surface::dispatchUnlockAndPost(va_list args) { + return unlockAndPost(); +} + + +int Surface::connect(int api) { + ATRACE_CALL(); + ALOGV("Surface::connect"); + Mutex::Autolock lock(mMutex); + IGraphicBufferProducer::QueueBufferOutput output; + int err = mGraphicBufferProducer->connect(api, &output); + if (err == NO_ERROR) { + uint32_t numPendingBuffers = 0; + output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, + &numPendingBuffers); + mConsumerRunningBehind = (numPendingBuffers >= 2); } - if (surface->mSurface == NULL && surface->getISurfaceTexture() == NULL) { - surface = 0; + if (!err && api == NATIVE_WINDOW_API_CPU) { + mConnectedToCpu = true; } - cleanCachedSurfacesLocked(); - return surface; + return err; } -// Remove the stale entries from the surface cache. This should only be called -// with sCachedSurfacesLock held. -void Surface::cleanCachedSurfacesLocked() { - for (int i = sCachedSurfaces.size()-1; i >= 0; --i) { - wp<Surface> s(sCachedSurfaces.valueAt(i)); - if (s == 0 || s.promote() == 0) { - sCachedSurfaces.removeItemsAt(i); +int Surface::disconnect(int api) { + ATRACE_CALL(); + ALOGV("Surface::disconnect"); + Mutex::Autolock lock(mMutex); + freeAllBuffers(); + int err = mGraphicBufferProducer->disconnect(api); + if (!err) { + mReqFormat = 0; + mReqWidth = 0; + mReqHeight = 0; + mReqUsage = 0; + mCrop.clear(); + mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; + mTransform = 0; + if (api == NATIVE_WINDOW_API_CPU) { + mConnectedToCpu = false; } } + return err; } -void Surface::init(const sp<IGraphicBufferProducer>& bufferProducer) +int Surface::setUsage(uint32_t reqUsage) { - if (mSurface != NULL || bufferProducer != NULL) { - ALOGE_IF(bufferProducer==0, "got a NULL IGraphicBufferProducer from ISurface"); - if (bufferProducer != NULL) { - setISurfaceTexture(bufferProducer); - setUsage(GraphicBuffer::USAGE_HW_RENDER); - } + ALOGV("Surface::setUsage"); + Mutex::Autolock lock(mMutex); + mReqUsage = reqUsage; + return OK; +} - // TODO: the display metrics should come from the display manager - DisplayInfo dinfo; - sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain); - SurfaceComposerClient::getDisplayInfo(display, &dinfo); - const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi; - const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi; - const_cast<uint32_t&>(ANativeWindow::flags) = 0; +int Surface::setCrop(Rect const* rect) +{ + ATRACE_CALL(); + + Rect realRect; + if (rect == NULL || rect->isEmpty()) { + realRect.clear(); + } else { + realRect = *rect; } + + ALOGV("Surface::setCrop rect=[%d %d %d %d]", + realRect.left, realRect.top, realRect.right, realRect.bottom); + + Mutex::Autolock lock(mMutex); + mCrop = realRect; + return NO_ERROR; } -Surface::~Surface() +int Surface::setBufferCount(int bufferCount) { - // clear all references and trigger an IPC now, to make sure things - // happen without delay, since these resources are quite heavy. - mSurface.clear(); - IPCThreadState::self()->flushCommands(); + ATRACE_CALL(); + ALOGV("Surface::setBufferCount"); + Mutex::Autolock lock(mMutex); + + status_t err = mGraphicBufferProducer->setBufferCount(bufferCount); + ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s", + bufferCount, strerror(-err)); + + if (err == NO_ERROR) { + freeAllBuffers(); + } + + return err; } -bool Surface::isValid() { - return getISurfaceTexture() != NULL; +int Surface::setBuffersDimensions(int w, int h) +{ + ATRACE_CALL(); + ALOGV("Surface::setBuffersDimensions"); + + if (w<0 || h<0) + return BAD_VALUE; + + if ((w && !h) || (!w && h)) + return BAD_VALUE; + + Mutex::Autolock lock(mMutex); + mReqWidth = w; + mReqHeight = h; + return NO_ERROR; } -sp<IGraphicBufferProducer> Surface::getSurfaceTexture() { - return getISurfaceTexture(); +int Surface::setBuffersUserDimensions(int w, int h) +{ + ATRACE_CALL(); + ALOGV("Surface::setBuffersUserDimensions"); + + if (w<0 || h<0) + return BAD_VALUE; + + if ((w && !h) || (!w && h)) + return BAD_VALUE; + + Mutex::Autolock lock(mMutex); + mUserWidth = w; + mUserHeight = h; + return NO_ERROR; } -sp<IBinder> Surface::asBinder() const { - return mSurface!=0 ? mSurface->asBinder() : 0; +int Surface::setBuffersFormat(int format) +{ + ALOGV("Surface::setBuffersFormat"); + + if (format<0) + return BAD_VALUE; + + Mutex::Autolock lock(mMutex); + mReqFormat = format; + return NO_ERROR; } -// ---------------------------------------------------------------------------- +int Surface::setScalingMode(int mode) +{ + ATRACE_CALL(); + ALOGV("Surface::setScalingMode(%d)", mode); + + switch (mode) { + case NATIVE_WINDOW_SCALING_MODE_FREEZE: + case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: + case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: + break; + default: + ALOGE("unknown scaling mode: %d", mode); + return BAD_VALUE; + } -int Surface::query(int what, int* value) const { - switch (what) { - case NATIVE_WINDOW_CONCRETE_TYPE: - *value = NATIVE_WINDOW_SURFACE; - return NO_ERROR; + Mutex::Autolock lock(mMutex); + mScalingMode = mode; + return NO_ERROR; +} + +int Surface::setBuffersTransform(int transform) +{ + ATRACE_CALL(); + ALOGV("Surface::setBuffersTransform"); + Mutex::Autolock lock(mMutex); + mTransform = transform; + return NO_ERROR; +} + +int Surface::setBuffersTimestamp(int64_t timestamp) +{ + ALOGV("Surface::setBuffersTimestamp"); + Mutex::Autolock lock(mMutex); + mTimestamp = timestamp; + return NO_ERROR; +} + +void Surface::freeAllBuffers() { + for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { + mSlots[i].buffer = 0; } - return SurfaceTextureClient::query(what, value); } -// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------- +// the lock/unlock APIs must be used from the same thread + +static status_t copyBlt( + const sp<GraphicBuffer>& dst, + const sp<GraphicBuffer>& src, + const Region& reg) +{ + // src and dst with, height and format must be identical. no verification + // is done here. + status_t err; + uint8_t const * src_bits = NULL; + err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); + ALOGE_IF(err, "error locking src buffer %s", strerror(-err)); + + uint8_t* dst_bits = NULL; + err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); + ALOGE_IF(err, "error locking dst buffer %s", strerror(-err)); + + Region::const_iterator head(reg.begin()); + Region::const_iterator tail(reg.end()); + if (head != tail && src_bits && dst_bits) { + const size_t bpp = bytesPerPixel(src->format); + const size_t dbpr = dst->stride * bpp; + const size_t sbpr = src->stride * bpp; + + while (head != tail) { + const Rect& r(*head++); + ssize_t h = r.height(); + if (h <= 0) continue; + size_t size = r.width() * bpp; + uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; + uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; + if (dbpr==sbpr && size==sbpr) { + size *= h; + h = 1; + } + do { + memcpy(d, s, size); + d += dbpr; + s += sbpr; + } while (--h > 0); + } + } + + if (src_bits) + src->unlock(); -status_t Surface::lock(SurfaceInfo* other, Region* inOutDirtyRegion) { - ANativeWindow_Buffer outBuffer; + if (dst_bits) + dst->unlock(); + + return err; +} - ARect temp; - ARect* inOutDirtyBounds = NULL; - if (inOutDirtyRegion) { - temp = inOutDirtyRegion->getBounds(); - inOutDirtyBounds = &temp; +// ---------------------------------------------------------------------------- + +status_t Surface::writeToParcel( + const sp<Surface>& surface, Parcel* parcel) { + sp<IGraphicBufferProducer> bp; + if (surface != NULL) { + bp = surface->mGraphicBufferProducer; } + return parcel->writeStrongBinder(bp->asBinder()); +} - status_t err = SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds); +sp<Surface> Surface::readFromParcel(const Parcel& data) { + sp<IBinder> binder(data.readStrongBinder()); + sp<IGraphicBufferProducer> bp(interface_cast<IGraphicBufferProducer>(binder)); + return new Surface(bp); +} - if (err == NO_ERROR) { - other->w = uint32_t(outBuffer.width); - other->h = uint32_t(outBuffer.height); - other->s = uint32_t(outBuffer.stride); - other->usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; - other->format = uint32_t(outBuffer.format); - other->bits = outBuffer.bits; +// ---------------------------------------------------------------------------- + +status_t Surface::lock( + ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds) +{ + if (mLockedBuffer != 0) { + ALOGE("Surface::lock failed, already locked"); + return INVALID_OPERATION; } - if (inOutDirtyRegion) { - inOutDirtyRegion->set( static_cast<Rect const&>(temp) ); + if (!mConnectedToCpu) { + int err = Surface::connect(NATIVE_WINDOW_API_CPU); + if (err) { + return err; + } + // we're intending to do software rendering from this point + setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); } + ANativeWindowBuffer* out; + int fenceFd = -1; + status_t err = dequeueBuffer(&out, &fenceFd); + ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); + if (err == NO_ERROR) { + sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); + sp<Fence> fence(new Fence(fenceFd)); + + err = fence->waitForever(1000, "Surface::lock"); + if (err != OK) { + ALOGE("Fence::wait failed (%s)", strerror(-err)); + cancelBuffer(out, fenceFd); + return err; + } + + const Rect bounds(backBuffer->width, backBuffer->height); + + Region newDirtyRegion; + if (inOutDirtyBounds) { + newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds)); + newDirtyRegion.andSelf(bounds); + } else { + newDirtyRegion.set(bounds); + } + + // figure out if we can copy the frontbuffer back + const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); + const bool canCopyBack = (frontBuffer != 0 && + backBuffer->width == frontBuffer->width && + backBuffer->height == frontBuffer->height && + backBuffer->format == frontBuffer->format); + + if (canCopyBack) { + // copy the area that is invalid and not repainted this round + const Region copyback(mDirtyRegion.subtract(newDirtyRegion)); + if (!copyback.isEmpty()) + copyBlt(backBuffer, frontBuffer, copyback); + } else { + // if we can't copy-back anything, modify the user's dirty + // region to make sure they redraw the whole buffer + newDirtyRegion.set(bounds); + mDirtyRegion.clear(); + Mutex::Autolock lock(mMutex); + for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) { + mSlots[i].dirtyRegion.clear(); + } + } + + + { // scope for the lock + Mutex::Autolock lock(mMutex); + int backBufferSlot(getSlotFromBufferLocked(backBuffer.get())); + if (backBufferSlot >= 0) { + Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion); + mDirtyRegion.subtract(dirtyRegion); + dirtyRegion = newDirtyRegion; + } + } + + mDirtyRegion.orSelf(newDirtyRegion); + if (inOutDirtyBounds) { + *inOutDirtyBounds = newDirtyRegion.getBounds(); + } + + void* vaddr; + status_t res = backBuffer->lock( + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + newDirtyRegion.bounds(), &vaddr); + + ALOGW_IF(res, "failed locking buffer (handle = %p)", + backBuffer->handle); + + if (res != 0) { + err = INVALID_OPERATION; + } else { + mLockedBuffer = backBuffer; + outBuffer->width = backBuffer->width; + outBuffer->height = backBuffer->height; + outBuffer->stride = backBuffer->stride; + outBuffer->format = backBuffer->format; + outBuffer->bits = vaddr; + } + } return err; } -status_t Surface::unlockAndPost() { - return SurfaceTextureClient::unlockAndPost(); +status_t Surface::unlockAndPost() +{ + if (mLockedBuffer == 0) { + ALOGE("Surface::unlockAndPost failed, no locked buffer"); + return INVALID_OPERATION; + } + + status_t err = mLockedBuffer->unlock(); + ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle); + + err = queueBuffer(mLockedBuffer.get(), -1); + ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)", + mLockedBuffer->handle, strerror(-err)); + + mPostedBuffer = mLockedBuffer; + mLockedBuffer = 0; + return err; } -// ---------------------------------------------------------------------------- }; // namespace android diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 0c6881a69d..e8e208f12b 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -31,6 +31,7 @@ #include <ui/DisplayInfo.h> +#include <gui/IGraphicBufferProducer.h> #include <gui/ISurface.h> #include <gui/ISurfaceComposer.h> #include <gui/ISurfaceComposerClient.h> @@ -128,7 +129,7 @@ class Composer : public Singleton<Composer> void setAnimationTransactionImpl(); layer_state_t* getLayerStateLocked( - const sp<SurfaceComposerClient>& client, SurfaceID id); + const sp<SurfaceComposerClient>& client, const sp<IBinder>& id); DisplayState& getDisplayStateLocked(const sp<IBinder>& token); @@ -136,26 +137,26 @@ public: sp<IBinder> createDisplay(const String8& displayName, bool secure); sp<IBinder> getBuiltInDisplay(int32_t id); - status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id, + status_t setPosition(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, float x, float y); - status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id, + status_t setSize(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, uint32_t w, uint32_t h); - status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id, + status_t setLayer(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, int32_t z); - status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id, + status_t setFlags(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, uint32_t flags, uint32_t mask); status_t setTransparentRegionHint( - const sp<SurfaceComposerClient>& client, SurfaceID id, + const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, const Region& transparentRegion); - status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id, + status_t setAlpha(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, float alpha); - status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id, + status_t setMatrix(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, float dsdx, float dtdx, float dsdy, float dtdy); status_t setOrientation(int orientation); - status_t setCrop(const sp<SurfaceComposerClient>& client, SurfaceID id, + status_t setCrop(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, const Rect& crop); status_t setLayerStack(const sp<SurfaceComposerClient>& client, - SurfaceID id, uint32_t layerStack); + const sp<IBinder>& id, uint32_t layerStack); void setDisplaySurface(const sp<IBinder>& token, const sp<IGraphicBufferProducer>& bufferProducer); @@ -241,7 +242,7 @@ void Composer::setAnimationTransactionImpl() { } layer_state_t* Composer::getLayerStateLocked( - const sp<SurfaceComposerClient>& client, SurfaceID id) { + const sp<SurfaceComposerClient>& client, const sp<IBinder>& id) { ComposerState s; s.client = client->mClient; @@ -258,7 +259,7 @@ layer_state_t* Composer::getLayerStateLocked( } status_t Composer::setPosition(const sp<SurfaceComposerClient>& client, - SurfaceID id, float x, float y) { + const sp<IBinder>& id, float x, float y) { Mutex::Autolock _l(mLock); layer_state_t* s = getLayerStateLocked(client, id); if (!s) @@ -270,7 +271,7 @@ status_t Composer::setPosition(const sp<SurfaceComposerClient>& client, } status_t Composer::setSize(const sp<SurfaceComposerClient>& client, - SurfaceID id, uint32_t w, uint32_t h) { + const sp<IBinder>& id, uint32_t w, uint32_t h) { Mutex::Autolock _l(mLock); layer_state_t* s = getLayerStateLocked(client, id); if (!s) @@ -286,7 +287,7 @@ status_t Composer::setSize(const sp<SurfaceComposerClient>& client, } status_t Composer::setLayer(const sp<SurfaceComposerClient>& client, - SurfaceID id, int32_t z) { + const sp<IBinder>& id, int32_t z) { Mutex::Autolock _l(mLock); layer_state_t* s = getLayerStateLocked(client, id); if (!s) @@ -297,7 +298,7 @@ status_t Composer::setLayer(const sp<SurfaceComposerClient>& client, } status_t Composer::setFlags(const sp<SurfaceComposerClient>& client, - SurfaceID id, uint32_t flags, + const sp<IBinder>& id, uint32_t flags, uint32_t mask) { Mutex::Autolock _l(mLock); layer_state_t* s = getLayerStateLocked(client, id); @@ -311,7 +312,7 @@ status_t Composer::setFlags(const sp<SurfaceComposerClient>& client, } status_t Composer::setTransparentRegionHint( - const sp<SurfaceComposerClient>& client, SurfaceID id, + const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, const Region& transparentRegion) { Mutex::Autolock _l(mLock); layer_state_t* s = getLayerStateLocked(client, id); @@ -323,7 +324,7 @@ status_t Composer::setTransparentRegionHint( } status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client, - SurfaceID id, float alpha) { + const sp<IBinder>& id, float alpha) { Mutex::Autolock _l(mLock); layer_state_t* s = getLayerStateLocked(client, id); if (!s) @@ -334,7 +335,7 @@ status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client, } status_t Composer::setLayerStack(const sp<SurfaceComposerClient>& client, - SurfaceID id, uint32_t layerStack) { + const sp<IBinder>& id, uint32_t layerStack) { Mutex::Autolock _l(mLock); layer_state_t* s = getLayerStateLocked(client, id); if (!s) @@ -345,7 +346,7 @@ status_t Composer::setLayerStack(const sp<SurfaceComposerClient>& client, } status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client, - SurfaceID id, float dsdx, float dtdx, + const sp<IBinder>& id, float dsdx, float dtdx, float dsdy, float dtdy) { Mutex::Autolock _l(mLock); layer_state_t* s = getLayerStateLocked(client, id); @@ -362,7 +363,7 @@ status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client, } status_t Composer::setCrop(const sp<SurfaceComposerClient>& client, - SurfaceID id, const Rect& crop) { + const sp<IBinder>& id, const Rect& crop) { Mutex::Autolock _l(mLock); layer_state_t* s = getLayerStateLocked(client, id); if (!s) @@ -472,11 +473,9 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface( { sp<SurfaceControl> result; if (mStatus == NO_ERROR) { - ISurfaceComposerClient::surface_data_t data; - sp<ISurface> surface = mClient->createSurface(&data, name, - w, h, format, flags); + sp<ISurface> surface = mClient->createSurface(name, w, h, format, flags); if (surface != 0) { - result = new SurfaceControl(this, surface, data); + result = new SurfaceControl(this, surface); } } return result; @@ -491,7 +490,7 @@ sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) { return Composer::getInstance().getBuiltInDisplay(id); } -status_t SurfaceComposerClient::destroySurface(SurfaceID sid) { +status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) { if (mStatus != NO_ERROR) return mStatus; status_t err = mClient->destroySurface(sid); @@ -518,53 +517,53 @@ void SurfaceComposerClient::setAnimationTransaction() { // ---------------------------------------------------------------------------- -status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) { +status_t SurfaceComposerClient::setCrop(const sp<IBinder>& id, const Rect& crop) { return getComposer().setCrop(this, id, crop); } -status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) { +status_t SurfaceComposerClient::setPosition(const sp<IBinder>& id, float x, float y) { return getComposer().setPosition(this, id, x, y); } -status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) { +status_t SurfaceComposerClient::setSize(const sp<IBinder>& id, uint32_t w, uint32_t h) { return getComposer().setSize(this, id, w, h); } -status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) { +status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) { return getComposer().setLayer(this, id, z); } -status_t SurfaceComposerClient::hide(SurfaceID id) { +status_t SurfaceComposerClient::hide(const sp<IBinder>& id) { return getComposer().setFlags(this, id, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden); } -status_t SurfaceComposerClient::show(SurfaceID id) { +status_t SurfaceComposerClient::show(const sp<IBinder>& id) { return getComposer().setFlags(this, id, 0, layer_state_t::eLayerHidden); } -status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags, +status_t SurfaceComposerClient::setFlags(const sp<IBinder>& id, uint32_t flags, uint32_t mask) { return getComposer().setFlags(this, id, flags, mask); } -status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id, +status_t SurfaceComposerClient::setTransparentRegionHint(const sp<IBinder>& id, const Region& transparentRegion) { return getComposer().setTransparentRegionHint(this, id, transparentRegion); } -status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) { +status_t SurfaceComposerClient::setAlpha(const sp<IBinder>& id, float alpha) { return getComposer().setAlpha(this, id, alpha); } -status_t SurfaceComposerClient::setLayerStack(SurfaceID id, uint32_t layerStack) { +status_t SurfaceComposerClient::setLayerStack(const sp<IBinder>& id, uint32_t layerStack) { return getComposer().setLayerStack(this, id, layerStack); } -status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx, +status_t SurfaceComposerClient::setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dsdy, float dtdy) { return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy); } diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp new file mode 100644 index 0000000000..e621b22a05 --- /dev/null +++ b/libs/gui/SurfaceControl.cpp @@ -0,0 +1,194 @@ +/* + * 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 "SurfaceControl" + +#include <stdint.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <android/native_window.h> + +#include <utils/CallStack.h> +#include <utils/Errors.h> +#include <utils/Log.h> +#include <utils/threads.h> + +#include <binder/IPCThreadState.h> + +#include <ui/DisplayInfo.h> +#include <ui/GraphicBuffer.h> +#include <ui/Rect.h> + +#include <gui/ISurface.h> +#include <gui/ISurfaceComposer.h> +#include <gui/Surface.h> +#include <gui/SurfaceComposerClient.h> +#include <gui/SurfaceControl.h> + +namespace android { + +// ============================================================================ +// SurfaceControl +// ============================================================================ + +SurfaceControl::SurfaceControl( + const sp<SurfaceComposerClient>& client, + const sp<ISurface>& surface) + : mClient(client) +{ + if (surface != 0) { + mSurface = surface->asBinder(); + mGraphicBufferProducer = surface->getSurfaceTexture(); + } +} + +SurfaceControl::~SurfaceControl() +{ + destroy(); +} + +void SurfaceControl::destroy() +{ + if (isValid()) { + mClient->destroySurface(mSurface); + } + // 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(); + mGraphicBufferProducer.clear(); + IPCThreadState::self()->flushCommands(); +} + +void SurfaceControl::clear() +{ + // here, the window manager tells us explicitly that we should destroy + // the surface's resource. Soon after this call, it will also release + // its last reference (which will call the dtor); however, it is possible + // that a client living in the same process still holds references which + // would delay the call to the dtor -- that is why we need this explicit + // "clear()" call. + destroy(); +} + +bool SurfaceControl::isSameSurface( + const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) +{ + if (lhs == 0 || rhs == 0) + return false; + return lhs->mSurface == rhs->mSurface; +} + +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); +} +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); +} +status_t SurfaceControl::setPosition(float x, float y) { + status_t err = validate(); + if (err < 0) return err; + const sp<SurfaceComposerClient>& client(mClient); + return client->setPosition(mSurface, 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); +} +status_t SurfaceControl::hide() { + status_t err = validate(); + if (err < 0) return err; + const sp<SurfaceComposerClient>& client(mClient); + return client->hide(mSurface); +} +status_t SurfaceControl::show() { + status_t err = validate(); + if (err < 0) return err; + const sp<SurfaceComposerClient>& client(mClient); + return client->show(mSurface); +} +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); +} +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); +} +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); +} +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); +} +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); +} + +status_t SurfaceControl::validate() const +{ + if (mSurface==0 || mClient==0) { + ALOGE("invalid ISurface (%p) or client (%p)", + mSurface.get(), mClient.get()); + return NO_INIT; + } + return NO_ERROR; +} + +status_t SurfaceControl::writeSurfaceToParcel( + const sp<SurfaceControl>& control, Parcel* parcel) +{ + sp<IGraphicBufferProducer> bp; + if (control != NULL) { + bp = control->mGraphicBufferProducer; + } + return parcel->writeStrongBinder(bp->asBinder()); +} + +sp<Surface> SurfaceControl::getSurface() const +{ + Mutex::Autolock _l(mLock); + if (mSurfaceData == 0) { + mSurfaceData = new Surface(mGraphicBufferProducer); + } + return mSurfaceData; +} + +// ---------------------------------------------------------------------------- +}; // namespace android diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp deleted file mode 100644 index c015b812f0..0000000000 --- a/libs/gui/SurfaceTextureClient.cpp +++ /dev/null @@ -1,846 +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. - */ - -#define LOG_TAG "SurfaceTextureClient" -#define ATRACE_TAG ATRACE_TAG_GRAPHICS -//#define LOG_NDEBUG 0 - -#include <android/native_window.h> - -#include <utils/Log.h> -#include <utils/Trace.h> - -#include <ui/Fence.h> - -#include <gui/ISurfaceComposer.h> -#include <gui/SurfaceComposerClient.h> -#include <gui/GLConsumer.h> -#include <gui/SurfaceTextureClient.h> - -#include <private/gui/ComposerService.h> - -namespace android { - -SurfaceTextureClient::SurfaceTextureClient( - const sp<IGraphicBufferProducer>& bufferProducer) -{ - SurfaceTextureClient::init(); - SurfaceTextureClient::setISurfaceTexture(bufferProducer); -} - -SurfaceTextureClient::SurfaceTextureClient() { - SurfaceTextureClient::init(); -} - -SurfaceTextureClient::~SurfaceTextureClient() { - if (mConnectedToCpu) { - SurfaceTextureClient::disconnect(NATIVE_WINDOW_API_CPU); - } -} - -void SurfaceTextureClient::init() { - // Initialize the ANativeWindow function pointers. - ANativeWindow::setSwapInterval = hook_setSwapInterval; - ANativeWindow::dequeueBuffer = hook_dequeueBuffer; - ANativeWindow::cancelBuffer = hook_cancelBuffer; - ANativeWindow::queueBuffer = hook_queueBuffer; - ANativeWindow::query = hook_query; - ANativeWindow::perform = hook_perform; - - ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED; - ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED; - ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED; - ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED; - - const_cast<int&>(ANativeWindow::minSwapInterval) = 0; - const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; - - mReqWidth = 0; - mReqHeight = 0; - mReqFormat = 0; - mReqUsage = 0; - mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; - mCrop.clear(); - mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; - mTransform = 0; - mDefaultWidth = 0; - mDefaultHeight = 0; - mUserWidth = 0; - mUserHeight = 0; - mTransformHint = 0; - mConsumerRunningBehind = false; - mConnectedToCpu = false; -} - -void SurfaceTextureClient::setISurfaceTexture( - const sp<IGraphicBufferProducer>& bufferProducer) -{ - mSurfaceTexture = bufferProducer; -} - -sp<IGraphicBufferProducer> SurfaceTextureClient::getISurfaceTexture() const { - return mSurfaceTexture; -} - -int SurfaceTextureClient::hook_setSwapInterval(ANativeWindow* window, int interval) { - SurfaceTextureClient* c = getSelf(window); - return c->setSwapInterval(interval); -} - -int SurfaceTextureClient::hook_dequeueBuffer(ANativeWindow* window, - ANativeWindowBuffer** buffer, int* fenceFd) { - SurfaceTextureClient* c = getSelf(window); - return c->dequeueBuffer(buffer, fenceFd); -} - -int SurfaceTextureClient::hook_cancelBuffer(ANativeWindow* window, - ANativeWindowBuffer* buffer, int fenceFd) { - SurfaceTextureClient* c = getSelf(window); - return c->cancelBuffer(buffer, fenceFd); -} - -int SurfaceTextureClient::hook_queueBuffer(ANativeWindow* window, - ANativeWindowBuffer* buffer, int fenceFd) { - SurfaceTextureClient* c = getSelf(window); - return c->queueBuffer(buffer, fenceFd); -} - -int SurfaceTextureClient::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer** buffer) { - SurfaceTextureClient* c = getSelf(window); - ANativeWindowBuffer* buf; - int fenceFd = -1; - int result = c->dequeueBuffer(&buf, &fenceFd); - sp<Fence> fence(new Fence(fenceFd)); - int waitResult = fence->waitForever(1000, "dequeueBuffer_DEPRECATED"); - if (waitResult != OK) { - ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d", - waitResult); - c->cancelBuffer(buf, -1); - return waitResult; - } - *buffer = buf; - return result; -} - -int SurfaceTextureClient::hook_cancelBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer* buffer) { - SurfaceTextureClient* c = getSelf(window); - return c->cancelBuffer(buffer, -1); -} - -int SurfaceTextureClient::hook_lockBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer* buffer) { - SurfaceTextureClient* c = getSelf(window); - return c->lockBuffer_DEPRECATED(buffer); -} - -int SurfaceTextureClient::hook_queueBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer* buffer) { - SurfaceTextureClient* c = getSelf(window); - return c->queueBuffer(buffer, -1); -} - -int SurfaceTextureClient::hook_query(const ANativeWindow* window, - int what, int* value) { - const SurfaceTextureClient* c = getSelf(window); - return c->query(what, value); -} - -int SurfaceTextureClient::hook_perform(ANativeWindow* window, int operation, ...) { - va_list args; - va_start(args, operation); - SurfaceTextureClient* c = getSelf(window); - return c->perform(operation, args); -} - -int SurfaceTextureClient::setSwapInterval(int interval) { - ATRACE_CALL(); - // EGL specification states: - // interval is silently clamped to minimum and maximum implementation - // dependent values before being stored. - // Although we don't have to, we apply the same logic here. - - if (interval < minSwapInterval) - interval = minSwapInterval; - - if (interval > maxSwapInterval) - interval = maxSwapInterval; - - status_t res = mSurfaceTexture->setSynchronousMode(interval ? true : false); - - return res; -} - -int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer, - int* fenceFd) { - ATRACE_CALL(); - ALOGV("SurfaceTextureClient::dequeueBuffer"); - Mutex::Autolock lock(mMutex); - int buf = -1; - int reqW = mReqWidth ? mReqWidth : mUserWidth; - int reqH = mReqHeight ? mReqHeight : mUserHeight; - sp<Fence> fence; - status_t result = mSurfaceTexture->dequeueBuffer(&buf, fence, reqW, reqH, - mReqFormat, mReqUsage); - if (result < 0) { - ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d)" - "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage, - result); - return result; - } - sp<GraphicBuffer>& gbuf(mSlots[buf].buffer); - if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) { - freeAllBuffers(); - } - - if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) { - result = mSurfaceTexture->requestBuffer(buf, &gbuf); - if (result != NO_ERROR) { - ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", - result); - return result; - } - } - - if (fence.get()) { - *fenceFd = fence->dup(); - if (*fenceFd == -1) { - ALOGE("dequeueBuffer: error duping fence: %d", errno); - // dup() should never fail; something is badly wrong. Soldier on - // and hope for the best; the worst that should happen is some - // visible corruption that lasts until the next frame. - } - } else { - *fenceFd = -1; - } - - *buffer = gbuf.get(); - return OK; -} - -int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer, - int fenceFd) { - ATRACE_CALL(); - ALOGV("SurfaceTextureClient::cancelBuffer"); - Mutex::Autolock lock(mMutex); - int i = getSlotFromBufferLocked(buffer); - if (i < 0) { - return i; - } - sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : NULL); - mSurfaceTexture->cancelBuffer(i, fence); - return OK; -} - -int SurfaceTextureClient::getSlotFromBufferLocked( - android_native_buffer_t* buffer) const { - bool dumpedState = false; - for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { - if (mSlots[i].buffer != NULL && - mSlots[i].buffer->handle == buffer->handle) { - return i; - } - } - ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle); - return BAD_VALUE; -} - -int SurfaceTextureClient::lockBuffer_DEPRECATED(android_native_buffer_t* buffer) { - ALOGV("SurfaceTextureClient::lockBuffer"); - Mutex::Autolock lock(mMutex); - return OK; -} - -int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { - ATRACE_CALL(); - ALOGV("SurfaceTextureClient::queueBuffer"); - Mutex::Autolock lock(mMutex); - int64_t timestamp; - if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) { - timestamp = systemTime(SYSTEM_TIME_MONOTONIC); - ALOGV("SurfaceTextureClient::queueBuffer making up timestamp: %.2f ms", - timestamp / 1000000.f); - } else { - timestamp = mTimestamp; - } - int i = getSlotFromBufferLocked(buffer); - if (i < 0) { - return i; - } - - - // Make sure the crop rectangle is entirely inside the buffer. - Rect crop; - mCrop.intersect(Rect(buffer->width, buffer->height), &crop); - - sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : NULL); - IGraphicBufferProducer::QueueBufferOutput output; - IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode, - mTransform, fence); - status_t err = mSurfaceTexture->queueBuffer(i, input, &output); - if (err != OK) { - ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err); - } - uint32_t numPendingBuffers = 0; - output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, - &numPendingBuffers); - - mConsumerRunningBehind = (numPendingBuffers >= 2); - - return err; -} - -int SurfaceTextureClient::query(int what, int* value) const { - ATRACE_CALL(); - ALOGV("SurfaceTextureClient::query"); - { // scope for the lock - Mutex::Autolock lock(mMutex); - switch (what) { - case NATIVE_WINDOW_FORMAT: - if (mReqFormat) { - *value = mReqFormat; - return NO_ERROR; - } - break; - case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: { - sp<ISurfaceComposer> composer( - ComposerService::getComposerService()); - if (composer->authenticateSurfaceTexture(mSurfaceTexture)) { - *value = 1; - } else { - *value = 0; - } - return NO_ERROR; - } - case NATIVE_WINDOW_CONCRETE_TYPE: - *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT; - return NO_ERROR; - case NATIVE_WINDOW_DEFAULT_WIDTH: - *value = mUserWidth ? mUserWidth : mDefaultWidth; - return NO_ERROR; - case NATIVE_WINDOW_DEFAULT_HEIGHT: - *value = mUserHeight ? mUserHeight : mDefaultHeight; - return NO_ERROR; - case NATIVE_WINDOW_TRANSFORM_HINT: - *value = mTransformHint; - return NO_ERROR; - case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: { - status_t err = NO_ERROR; - if (!mConsumerRunningBehind) { - *value = 0; - } else { - err = mSurfaceTexture->query(what, value); - if (err == NO_ERROR) { - mConsumerRunningBehind = *value; - } - } - return err; - } - } - } - return mSurfaceTexture->query(what, value); -} - -int SurfaceTextureClient::perform(int operation, va_list args) -{ - int res = NO_ERROR; - switch (operation) { - case NATIVE_WINDOW_CONNECT: - // deprecated. must return NO_ERROR. - break; - case NATIVE_WINDOW_DISCONNECT: - // deprecated. must return NO_ERROR. - break; - case NATIVE_WINDOW_SET_USAGE: - res = dispatchSetUsage(args); - break; - case NATIVE_WINDOW_SET_CROP: - res = dispatchSetCrop(args); - break; - case NATIVE_WINDOW_SET_BUFFER_COUNT: - res = dispatchSetBufferCount(args); - break; - case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: - res = dispatchSetBuffersGeometry(args); - break; - case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: - res = dispatchSetBuffersTransform(args); - break; - case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: - res = dispatchSetBuffersTimestamp(args); - break; - case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: - res = dispatchSetBuffersDimensions(args); - break; - case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS: - res = dispatchSetBuffersUserDimensions(args); - break; - case NATIVE_WINDOW_SET_BUFFERS_FORMAT: - res = dispatchSetBuffersFormat(args); - break; - case NATIVE_WINDOW_LOCK: - res = dispatchLock(args); - break; - case NATIVE_WINDOW_UNLOCK_AND_POST: - res = dispatchUnlockAndPost(args); - break; - case NATIVE_WINDOW_SET_SCALING_MODE: - res = dispatchSetScalingMode(args); - break; - case NATIVE_WINDOW_API_CONNECT: - res = dispatchConnect(args); - break; - case NATIVE_WINDOW_API_DISCONNECT: - res = dispatchDisconnect(args); - break; - default: - res = NAME_NOT_FOUND; - break; - } - return res; -} - -int SurfaceTextureClient::dispatchConnect(va_list args) { - int api = va_arg(args, int); - return connect(api); -} - -int SurfaceTextureClient::dispatchDisconnect(va_list args) { - int api = va_arg(args, int); - return disconnect(api); -} - -int SurfaceTextureClient::dispatchSetUsage(va_list args) { - int usage = va_arg(args, int); - return setUsage(usage); -} - -int SurfaceTextureClient::dispatchSetCrop(va_list args) { - android_native_rect_t const* rect = va_arg(args, android_native_rect_t*); - return setCrop(reinterpret_cast<Rect const*>(rect)); -} - -int SurfaceTextureClient::dispatchSetBufferCount(va_list args) { - size_t bufferCount = va_arg(args, size_t); - return setBufferCount(bufferCount); -} - -int SurfaceTextureClient::dispatchSetBuffersGeometry(va_list args) { - int w = va_arg(args, int); - int h = va_arg(args, int); - int f = va_arg(args, int); - int err = setBuffersDimensions(w, h); - if (err != 0) { - return err; - } - return setBuffersFormat(f); -} - -int SurfaceTextureClient::dispatchSetBuffersDimensions(va_list args) { - int w = va_arg(args, int); - int h = va_arg(args, int); - return setBuffersDimensions(w, h); -} - -int SurfaceTextureClient::dispatchSetBuffersUserDimensions(va_list args) { - int w = va_arg(args, int); - int h = va_arg(args, int); - return setBuffersUserDimensions(w, h); -} - -int SurfaceTextureClient::dispatchSetBuffersFormat(va_list args) { - int f = va_arg(args, int); - return setBuffersFormat(f); -} - -int SurfaceTextureClient::dispatchSetScalingMode(va_list args) { - int m = va_arg(args, int); - return setScalingMode(m); -} - -int SurfaceTextureClient::dispatchSetBuffersTransform(va_list args) { - int transform = va_arg(args, int); - return setBuffersTransform(transform); -} - -int SurfaceTextureClient::dispatchSetBuffersTimestamp(va_list args) { - int64_t timestamp = va_arg(args, int64_t); - return setBuffersTimestamp(timestamp); -} - -int SurfaceTextureClient::dispatchLock(va_list args) { - ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*); - ARect* inOutDirtyBounds = va_arg(args, ARect*); - return lock(outBuffer, inOutDirtyBounds); -} - -int SurfaceTextureClient::dispatchUnlockAndPost(va_list args) { - return unlockAndPost(); -} - - -int SurfaceTextureClient::connect(int api) { - ATRACE_CALL(); - ALOGV("SurfaceTextureClient::connect"); - Mutex::Autolock lock(mMutex); - IGraphicBufferProducer::QueueBufferOutput output; - int err = mSurfaceTexture->connect(api, &output); - if (err == NO_ERROR) { - uint32_t numPendingBuffers = 0; - output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, - &numPendingBuffers); - mConsumerRunningBehind = (numPendingBuffers >= 2); - } - if (!err && api == NATIVE_WINDOW_API_CPU) { - mConnectedToCpu = true; - } - return err; -} - -int SurfaceTextureClient::disconnect(int api) { - ATRACE_CALL(); - ALOGV("SurfaceTextureClient::disconnect"); - Mutex::Autolock lock(mMutex); - freeAllBuffers(); - int err = mSurfaceTexture->disconnect(api); - if (!err) { - mReqFormat = 0; - mReqWidth = 0; - mReqHeight = 0; - mReqUsage = 0; - mCrop.clear(); - mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; - mTransform = 0; - if (api == NATIVE_WINDOW_API_CPU) { - mConnectedToCpu = false; - } - } - return err; -} - -int SurfaceTextureClient::setUsage(uint32_t reqUsage) -{ - ALOGV("SurfaceTextureClient::setUsage"); - Mutex::Autolock lock(mMutex); - mReqUsage = reqUsage; - return OK; -} - -int SurfaceTextureClient::setCrop(Rect const* rect) -{ - ATRACE_CALL(); - - Rect realRect; - if (rect == NULL || rect->isEmpty()) { - realRect.clear(); - } else { - realRect = *rect; - } - - ALOGV("SurfaceTextureClient::setCrop rect=[%d %d %d %d]", - realRect.left, realRect.top, realRect.right, realRect.bottom); - - Mutex::Autolock lock(mMutex); - mCrop = realRect; - return NO_ERROR; -} - -int SurfaceTextureClient::setBufferCount(int bufferCount) -{ - ATRACE_CALL(); - ALOGV("SurfaceTextureClient::setBufferCount"); - Mutex::Autolock lock(mMutex); - - status_t err = mSurfaceTexture->setBufferCount(bufferCount); - ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s", - bufferCount, strerror(-err)); - - if (err == NO_ERROR) { - freeAllBuffers(); - } - - return err; -} - -int SurfaceTextureClient::setBuffersDimensions(int w, int h) -{ - ATRACE_CALL(); - ALOGV("SurfaceTextureClient::setBuffersDimensions"); - - if (w<0 || h<0) - return BAD_VALUE; - - if ((w && !h) || (!w && h)) - return BAD_VALUE; - - Mutex::Autolock lock(mMutex); - mReqWidth = w; - mReqHeight = h; - return NO_ERROR; -} - -int SurfaceTextureClient::setBuffersUserDimensions(int w, int h) -{ - ATRACE_CALL(); - ALOGV("SurfaceTextureClient::setBuffersUserDimensions"); - - if (w<0 || h<0) - return BAD_VALUE; - - if ((w && !h) || (!w && h)) - return BAD_VALUE; - - Mutex::Autolock lock(mMutex); - mUserWidth = w; - mUserHeight = h; - return NO_ERROR; -} - -int SurfaceTextureClient::setBuffersFormat(int format) -{ - ALOGV("SurfaceTextureClient::setBuffersFormat"); - - if (format<0) - return BAD_VALUE; - - Mutex::Autolock lock(mMutex); - mReqFormat = format; - return NO_ERROR; -} - -int SurfaceTextureClient::setScalingMode(int mode) -{ - ATRACE_CALL(); - ALOGV("SurfaceTextureClient::setScalingMode(%d)", mode); - - switch (mode) { - case NATIVE_WINDOW_SCALING_MODE_FREEZE: - case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: - case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: - 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) -{ - ATRACE_CALL(); - ALOGV("SurfaceTextureClient::setBuffersTransform"); - Mutex::Autolock lock(mMutex); - mTransform = transform; - return NO_ERROR; -} - -int SurfaceTextureClient::setBuffersTimestamp(int64_t timestamp) -{ - ALOGV("SurfaceTextureClient::setBuffersTimestamp"); - Mutex::Autolock lock(mMutex); - mTimestamp = timestamp; - return NO_ERROR; -} - -void SurfaceTextureClient::freeAllBuffers() { - for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { - mSlots[i].buffer = 0; - } -} - -// ---------------------------------------------------------------------- -// the lock/unlock APIs must be used from the same thread - -static status_t copyBlt( - const sp<GraphicBuffer>& dst, - const sp<GraphicBuffer>& src, - const Region& reg) -{ - // src and dst with, height and format must be identical. no verification - // is done here. - status_t err; - uint8_t const * src_bits = NULL; - err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); - ALOGE_IF(err, "error locking src buffer %s", strerror(-err)); - - uint8_t* dst_bits = NULL; - err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); - ALOGE_IF(err, "error locking dst buffer %s", strerror(-err)); - - Region::const_iterator head(reg.begin()); - Region::const_iterator tail(reg.end()); - if (head != tail && src_bits && dst_bits) { - const size_t bpp = bytesPerPixel(src->format); - const size_t dbpr = dst->stride * bpp; - const size_t sbpr = src->stride * bpp; - - while (head != tail) { - const Rect& r(*head++); - ssize_t h = r.height(); - if (h <= 0) continue; - size_t size = r.width() * bpp; - uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; - uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; - if (dbpr==sbpr && size==sbpr) { - size *= h; - h = 1; - } - do { - memcpy(d, s, size); - d += dbpr; - s += sbpr; - } while (--h > 0); - } - } - - if (src_bits) - src->unlock(); - - if (dst_bits) - dst->unlock(); - - return err; -} - -// ---------------------------------------------------------------------------- - -status_t SurfaceTextureClient::lock( - ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds) -{ - if (mLockedBuffer != 0) { - ALOGE("Surface::lock failed, already locked"); - return INVALID_OPERATION; - } - - if (!mConnectedToCpu) { - int err = SurfaceTextureClient::connect(NATIVE_WINDOW_API_CPU); - if (err) { - return err; - } - // we're intending to do software rendering from this point - setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); - } - - ANativeWindowBuffer* out; - int fenceFd = -1; - status_t err = dequeueBuffer(&out, &fenceFd); - ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); - if (err == NO_ERROR) { - sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); - sp<Fence> fence(new Fence(fenceFd)); - - err = fence->waitForever(1000, "SurfaceTextureClient::lock"); - if (err != OK) { - ALOGE("Fence::wait failed (%s)", strerror(-err)); - cancelBuffer(out, fenceFd); - return err; - } - - const Rect bounds(backBuffer->width, backBuffer->height); - - Region newDirtyRegion; - if (inOutDirtyBounds) { - newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds)); - newDirtyRegion.andSelf(bounds); - } else { - newDirtyRegion.set(bounds); - } - - // figure out if we can copy the frontbuffer back - const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); - const bool canCopyBack = (frontBuffer != 0 && - backBuffer->width == frontBuffer->width && - backBuffer->height == frontBuffer->height && - backBuffer->format == frontBuffer->format); - - if (canCopyBack) { - // copy the area that is invalid and not repainted this round - const Region copyback(mDirtyRegion.subtract(newDirtyRegion)); - if (!copyback.isEmpty()) - copyBlt(backBuffer, frontBuffer, copyback); - } else { - // if we can't copy-back anything, modify the user's dirty - // region to make sure they redraw the whole buffer - newDirtyRegion.set(bounds); - mDirtyRegion.clear(); - Mutex::Autolock lock(mMutex); - for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) { - mSlots[i].dirtyRegion.clear(); - } - } - - - { // scope for the lock - Mutex::Autolock lock(mMutex); - int backBufferSlot(getSlotFromBufferLocked(backBuffer.get())); - if (backBufferSlot >= 0) { - Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion); - mDirtyRegion.subtract(dirtyRegion); - dirtyRegion = newDirtyRegion; - } - } - - mDirtyRegion.orSelf(newDirtyRegion); - if (inOutDirtyBounds) { - *inOutDirtyBounds = newDirtyRegion.getBounds(); - } - - void* vaddr; - status_t res = backBuffer->lock( - GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - newDirtyRegion.bounds(), &vaddr); - - ALOGW_IF(res, "failed locking buffer (handle = %p)", - backBuffer->handle); - - if (res != 0) { - err = INVALID_OPERATION; - } else { - mLockedBuffer = backBuffer; - outBuffer->width = backBuffer->width; - outBuffer->height = backBuffer->height; - outBuffer->stride = backBuffer->stride; - outBuffer->format = backBuffer->format; - outBuffer->bits = vaddr; - } - } - return err; -} - -status_t SurfaceTextureClient::unlockAndPost() -{ - if (mLockedBuffer == 0) { - ALOGE("Surface::unlockAndPost failed, no locked buffer"); - return INVALID_OPERATION; - } - - status_t err = mLockedBuffer->unlock(); - ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle); - - err = queueBuffer(mLockedBuffer.get(), -1); - ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)", - mLockedBuffer->handle, strerror(-err)); - - mPostedBuffer = mLockedBuffer; - mLockedBuffer = 0; - return err; -} - -}; // namespace android diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 12cbfb0d7d..93f8fafc22 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -71,7 +71,7 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { sp<Fence> fence; sp<GraphicBuffer> buf; IGraphicBufferProducer::QueueBufferInput qbi(0, Rect(0, 0, 1, 1), - NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, fence); + NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); BufferQueue::BufferItem item; for (int i = 0; i < 2; i++) { diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp index 72a36bff79..12ae19ccef 100644 --- a/libs/gui/tests/CpuConsumer_test.cpp +++ b/libs/gui/tests/CpuConsumer_test.cpp @@ -26,7 +26,7 @@ #include <gtest/gtest.h> #include <gui/CpuConsumer.h> -#include <gui/SurfaceTextureClient.h> +#include <gui/Surface.h> #include <ui/GraphicBuffer.h> #include <utils/String8.h> #include <utils/Thread.h> @@ -64,7 +64,7 @@ protected: mCC = new CpuConsumer(params.maxLockedBuffers); String8 name("CpuConsumer_Under_Test"); mCC->setName(name); - mSTC = new SurfaceTextureClient(mCC->getProducerInterface()); + mSTC = new Surface(mCC->getProducerInterface()); mANW = mSTC; } @@ -149,7 +149,7 @@ protected: }; sp<CpuConsumer> mCC; - sp<SurfaceTextureClient> mSTC; + sp<Surface> mSTC; sp<ANativeWindow> mANW; }; diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp index 2df83a08d0..24b60f1afc 100644 --- a/libs/gui/tests/SurfaceTextureClient_test.cpp +++ b/libs/gui/tests/SurfaceTextureClient_test.cpp @@ -19,7 +19,7 @@ #include <EGL/egl.h> #include <gtest/gtest.h> -#include <gui/SurfaceTextureClient.h> +#include <gui/Surface.h> #include <system/graphics.h> #include <utils/Log.h> #include <utils/Thread.h> @@ -41,7 +41,7 @@ protected: testInfo->name()); mST = new GLConsumer(123); - mSTC = new SurfaceTextureClient(mST->getBufferQueue()); + mSTC = new Surface(mST->getBufferQueue()); mANW = mSTC; // We need a valid GL context so we can test updateTexImage() @@ -103,7 +103,7 @@ protected: } sp<GLConsumer> mST; - sp<SurfaceTextureClient> mSTC; + sp<Surface> mSTC; sp<ANativeWindow> mANW; EGLDisplay mEglDisplay; @@ -112,7 +112,7 @@ protected: }; TEST_F(SurfaceTextureClientTest, GetISurfaceTextureIsNotNull) { - sp<IGraphicBufferProducer> ist(mSTC->getISurfaceTexture()); + sp<IGraphicBufferProducer> ist(mSTC->getIGraphicBufferProducer()); ASSERT_TRUE(ist != NULL); } @@ -128,7 +128,7 @@ TEST_F(SurfaceTextureClientTest, ConcreteTypeIsSurfaceTextureClient) { int result = -123; int err = mANW->query(mANW.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result); EXPECT_EQ(NO_ERROR, err); - EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result); + EXPECT_EQ(NATIVE_WINDOW_SURFACE, result); } TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceSucceeds) { @@ -686,7 +686,7 @@ protected: for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { sp<GLConsumer> st(new GLConsumer(i)); - sp<SurfaceTextureClient> stc(new SurfaceTextureClient(st->getBufferQueue())); + sp<Surface> stc(new Surface(st->getBufferQueue())); mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig, static_cast<ANativeWindow*>(stc.get()), NULL); ASSERT_EQ(EGL_SUCCESS, eglGetError()); diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp index b6020ca2af..fbaf6aabba 100644 --- a/libs/gui/tests/SurfaceTexture_test.cpp +++ b/libs/gui/tests/SurfaceTexture_test.cpp @@ -19,7 +19,6 @@ #include <gtest/gtest.h> #include <gui/GLConsumer.h> -#include <gui/SurfaceTextureClient.h> #include <ui/GraphicBuffer.h> #include <utils/String8.h> #include <utils/threads.h> @@ -202,7 +201,6 @@ protected: while ((err = glGetError()) != GL_NO_ERROR) { msg += String8::format(", %#x", err); } - fprintf(stderr, "pixel check failure: %s\n", msg.string()); return ::testing::AssertionFailure( ::testing::Message(msg.string())); } @@ -228,7 +226,6 @@ protected: msg += String8::format("a(%d isn't %d)", pixel[3], a); } if (!msg.isEmpty()) { - fprintf(stderr, "pixel check failure: %s\n", msg.string()); return ::testing::AssertionFailure( ::testing::Message(msg.string())); } else { @@ -385,7 +382,7 @@ protected: virtual void SetUp() { GLTest::SetUp(); mST = new GLConsumer(TEX_ID); - mSTC = new SurfaceTextureClient(mST->getBufferQueue()); + mSTC = new Surface(mST->getBufferQueue()); mANW = mSTC; mTextureRenderer = new TextureRenderer(TEX_ID, mST); ASSERT_NO_FATAL_FAILURE(mTextureRenderer->SetUp()); @@ -576,7 +573,7 @@ protected: }; sp<GLConsumer> mST; - sp<SurfaceTextureClient> mSTC; + sp<Surface> mSTC; sp<ANativeWindow> mANW; sp<TextureRenderer> mTextureRenderer; sp<FrameWaiter> mFW; diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp index a01ac293ae..b9e0f00fb8 100644 --- a/libs/ui/Fence.cpp +++ b/libs/ui/Fence.cpp @@ -29,7 +29,7 @@ namespace android { -const sp<Fence> Fence::NO_FENCE = sp<Fence>(); +const sp<Fence> Fence::NO_FENCE = sp<Fence>(new Fence); Fence::Fence() : mFenceFd(-1) { @@ -71,7 +71,19 @@ status_t Fence::waitForever(unsigned int warningTimeout, const char* logname) { sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1, const sp<Fence>& f2) { ATRACE_CALL(); - int result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd); + int result; + // Merge the two fences. In the case where one of the fences is not a + // valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so + // that a new fence with the given name is created. + if (f1->isValid() && f2->isValid()) { + result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd); + } else if (f1->isValid()) { + result = sync_merge(name.string(), f1->mFenceFd, f1->mFenceFd); + } else if (f2->isValid()) { + result = sync_merge(name.string(), f2->mFenceFd, f2->mFenceFd); + } else { + return NO_FENCE; + } if (result == -1) { status_t err = -errno; ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)", @@ -83,9 +95,6 @@ sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1, } int Fence::dup() const { - if (mFenceFd == -1) { - return -1; - } return ::dup(mFenceFd); } @@ -121,22 +130,24 @@ size_t Fence::getFlattenedSize() const { } size_t Fence::getFdCount() const { - return 1; + return isValid() ? 1 : 0; } status_t Fence::flatten(void* buffer, size_t size, int fds[], size_t count) const { - if (size != 0 || count != 1) { + if (size != getFlattenedSize() || count != getFdCount()) { return BAD_VALUE; } - fds[0] = mFenceFd; + if (isValid()) { + fds[0] = mFenceFd; + } return NO_ERROR; } status_t Fence::unflatten(void const* buffer, size_t size, int fds[], size_t count) { - if (size != 0 || count != 1) { + if (size != 0 || (count != 0 && count != 1)) { return BAD_VALUE; } if (mFenceFd != -1) { @@ -144,7 +155,10 @@ status_t Fence::unflatten(void const* buffer, size_t size, int fds[], return INVALID_OPERATION; } - mFenceFd = fds[0]; + if (count == 1) { + mFenceFd = fds[0]; + } + return NO_ERROR; } diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk index 639c4d7e4b..1b3d6edfd7 100644 --- a/opengl/libagl/Android.mk +++ b/opengl/libagl/Android.mk @@ -34,16 +34,7 @@ ifeq ($(TARGET_ARCH),arm) LOCAL_CFLAGS += -fstrict-aliasing endif -ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) - LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER -endif - # we need to access the private Bionic header <bionic_tls.h> -# on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER -# behavior from the bionic Android.mk file -ifeq ($(TARGET_ARCH)-$(ARCH_ARM_HAVE_TLS_REGISTER),arm-true) - LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER -endif LOCAL_C_INCLUDES += bionic/libc/private LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index 6c35355948..ae170966de 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -37,11 +37,6 @@ LOCAL_LDLIBS := -lpthread -ldl LOCAL_MODULE:= libEGL LOCAL_LDFLAGS += -Wl,--exclude-libs=ALL LOCAL_SHARED_LIBRARIES += libdl -# Bionic's private TLS header relies on the ARCH_ARM_HAVE_TLS_REGISTER to -# select the appropriate TLS codepath -ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) - LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER -endif # we need to access the private Bionic header <bionic_tls.h> LOCAL_C_INCLUDES += bionic/libc/private @@ -63,10 +58,6 @@ ifeq ($(TARGET_BOARD_PLATFORM), s5pc110) LOCAL_CFLAGS += -DSYSTEMUI_PBSIZE_HACK=1 endif -ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) - LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER -endif - ifneq ($(MAX_EGL_CACHE_ENTRY_SIZE),) LOCAL_CFLAGS += -DMAX_EGL_CACHE_ENTRY_SIZE=$(MAX_EGL_CACHE_ENTRY_SIZE) endif @@ -100,19 +91,12 @@ LOCAL_MODULE:= libGLESv1_CM LOCAL_SHARED_LIBRARIES += libdl # we need to access the private Bionic header <bionic_tls.h> -ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) - LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER -endif LOCAL_C_INCLUDES += bionic/libc/private LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv1\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES LOCAL_CFLAGS += -fvisibility=hidden -ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) - LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER -endif - include $(BUILD_SHARED_LIBRARY) @@ -132,19 +116,12 @@ LOCAL_MODULE:= libGLESv2 LOCAL_SHARED_LIBRARIES += libdl # we need to access the private Bionic header <bionic_tls.h> -ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) - LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER -endif LOCAL_C_INCLUDES += bionic/libc/private LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv2\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES LOCAL_CFLAGS += -fvisibility=hidden -ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) - LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER -endif - include $(BUILD_SHARED_LIBRARY) ############################################################################### diff --git a/opengl/libs/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp index 8dcf38dbec..f453176549 100644 --- a/opengl/libs/EGL/getProcAddress.cpp +++ b/opengl/libs/EGL/getProcAddress.cpp @@ -37,14 +37,7 @@ namespace android { #if USE_FAST_TLS_KEY - #ifdef HAVE_ARM_TLS_REGISTER - #define GET_TLS(reg) \ - "mrc p15, 0, " #reg ", c13, c0, 3 \n" - #else - #define GET_TLS(reg) \ - "mov " #reg ", #0xFFFF0FFF \n" \ - "ldr " #reg ", [" #reg ", #-15] \n" - #endif + #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n" #define API_ENTRY(_api) __attribute__((naked)) _api diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp index 55ef499e26..fca42ec32a 100644 --- a/opengl/libs/GLES2/gl2.cpp +++ b/opengl/libs/GLES2/gl2.cpp @@ -41,14 +41,7 @@ using namespace android; #if USE_FAST_TLS_KEY - #ifdef HAVE_ARM_TLS_REGISTER - #define GET_TLS(reg) \ - "mrc p15, 0, " #reg ", c13, c0, 3 \n" - #else - #define GET_TLS(reg) \ - "mov " #reg ", #0xFFFF0FFF \n" \ - "ldr " #reg ", [" #reg ", #-15] \n" - #endif + #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n" #define API_ENTRY(_api) __attribute__((naked)) _api diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp index adcb60d711..48fd27877b 100644 --- a/opengl/libs/GLES_CM/gl.cpp +++ b/opengl/libs/GLES_CM/gl.cpp @@ -97,14 +97,7 @@ GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type, #if USE_FAST_TLS_KEY && !CHECK_FOR_GL_ERRORS - #ifdef HAVE_ARM_TLS_REGISTER - #define GET_TLS(reg) \ - "mrc p15, 0, " #reg ", c13, c0, 3 \n" - #else - #define GET_TLS(reg) \ - "mov " #reg ", #0xFFFF0FFF \n" \ - "ldr " #reg ", [" #reg ", #-15] \n" - #endif + #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n" #define API_ENTRY(_api) __attribute__((naked)) _api diff --git a/opengl/libs/GLES_trace/Android.mk b/opengl/libs/GLES_trace/Android.mk index 465b6b2c42..9dec020095 100644 --- a/opengl/libs/GLES_trace/Android.mk +++ b/opengl/libs/GLES_trace/Android.mk @@ -24,18 +24,9 @@ LOCAL_CFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI LOCAL_STATIC_LIBRARIES := libprotobuf-cpp-2.3.0-lite liblzf LOCAL_SHARED_LIBRARIES := libcutils libutils libstlport -ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) - LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER -endif - LOCAL_CFLAGS += -DLOG_TAG=\"libGLES_trace\" # we need to access the private Bionic header <bionic_tls.h> -# on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER -# behavior from the bionic Android.mk file -ifeq ($(TARGET_ARCH)-$(ARCH_ARM_HAVE_TLS_REGISTER),arm-true) - LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER -endif LOCAL_C_INCLUDES += bionic/libc/private LOCAL_MODULE:= libGLES_trace diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp index ec433fb083..c0daba2e6d 100644 --- a/opengl/tests/EGLTest/EGL_test.cpp +++ b/opengl/tests/EGLTest/EGL_test.cpp @@ -19,7 +19,7 @@ #include <utils/String8.h> #include <EGL/egl.h> -#include <gui/SurfaceTextureClient.h> +#include <gui/Surface.h> #include <gui/DummyConsumer.h> @@ -104,7 +104,7 @@ TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) { // Create a EGLSurface sp<BufferQueue> bq = new BufferQueue(); bq->consumerConnect(new DummyConsumer()); - sp<SurfaceTextureClient> mSTC = new SurfaceTextureClient(static_cast<sp<IGraphicBufferProducer> >( bq)); + sp<Surface> mSTC = new Surface(static_cast<sp<IGraphicBufferProducer> >( bq)); sp<ANativeWindow> mANW = mSTC; EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, diff --git a/opengl/tools/glgen/gen b/opengl/tools/glgen/gen index 3359a22729..fb3c3a9519 100755 --- a/opengl/tools/glgen/gen +++ b/opengl/tools/glgen/gen @@ -27,7 +27,7 @@ echo "package android.app; import android.content.pm.IPackageManager; public cla echo "package android.content.pm; public class ApplicationInfo {public int targetSdkVersion;}" > out/android/content/pm/ApplicationInfo.java echo "package android.content.pm; public interface IPackageManager {ApplicationInfo getApplicationInfo(java.lang.String packageName, int flags, java.lang.String userId) throws android.os.RemoteException;}" > out/android/content/pm/IPackageManager.java echo "package android.os; public class Build {public static class VERSION_CODES { public static final int CUPCAKE = 3;}; }" > out/android/os/Build.java -echo "package android.os; public class UserId {public static String myUserId() { return \"\"; } }" > out/android/os/UserId.java +echo "package android.os; public class UserHandle {public static String myUserId() { return \"\"; } }" > out/android/os/UserHandle.java echo "package android.os; public class RemoteException extends Exception {}" > out/android/os/RemoteException.java echo "package android.util; public class Log {public static void w(String a, String b) {} public static void e(String a, String b) {}}" > out/android/util/Log.java diff --git a/opengl/tools/glgen/specs/gles11/checks.spec b/opengl/tools/glgen/specs/gles11/checks.spec index f478a32516..165d0b4150 100644 --- a/opengl/tools/glgen/specs/gles11/checks.spec +++ b/opengl/tools/glgen/specs/gles11/checks.spec @@ -1,42 +1,41 @@ +glBufferData nullAllowed check data size +glBufferSubData check data size glClipPlanef check eqn 4 glClipPlanex check eqn 4 -glGetClipPlanefOES check eqn 4 -glGetClipPlanexOES check eqn 4 glDeleteBuffers check buffers n +glDeleteFramebuffersOES check framebuffers n +glDeleteRenderbuffersOES check renderbuffers n glDeleteTextures check textures n glDrawElements check_AIOOBE indices count +glDrawTexfvOES check coords 5 +glDrawTexivOES check coords 5 +glDrawTexsvOES check coords 5 +glDrawTexxvOES check coords 5 glFog ifcheck params 1 pname GL_FOG_MODE,GL_FOG_DENSITY,GL_FOG_START,GL_FOG_END ifcheck params 4 pname GL_FOG_COLOR glGenBuffers check buffers n +glGenFramebuffersOES check framebuffers n +glGenRenderbuffersOES check renderbuffers n glGenTextures check textures n +glGetBufferParameter check params 1 glGetClipPlane check eqn 4 +glGetClipPlanefOES check eqn 4 +glGetClipPlanexOES check eqn 4 +glGetFramebufferAttachmentParameterivOES check params 1 glGetIntegerv ifcheck params 1 pname GL_ALPHA_BITS,GL_ALPHA_TEST_FUNC,GL_ALPHA_TEST_REF,GL_BLEND_DST,GL_BLUE_BITS,GL_COLOR_ARRAY_BUFFER_BINDING,GL_COLOR_ARRAY_SIZE,GL_COLOR_ARRAY_STRIDE,GL_COLOR_ARRAY_TYPE,GL_CULL_FACE,GL_DEPTH_BITS,GL_DEPTH_CLEAR_VALUE,GL_DEPTH_FUNC,GL_DEPTH_WRITEMASK,GL_FOG_DENSITY,GL_FOG_END,GL_FOG_MODE,GL_FOG_START,GL_FRONT_FACE,GL_GREEN_BITS,GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES,GL_IMPLEMENTATION_COLOR_READ_TYPE_OES,GL_LIGHT_MODEL_COLOR_CONTROL,GL_LIGHT_MODEL_LOCAL_VIEWER,GL_LIGHT_MODEL_TWO_SIDE,GL_LINE_SMOOTH_HINT,GL_LINE_WIDTH,GL_LOGIC_OP_MODE,GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES,GL_MATRIX_INDEX_ARRAY_SIZE_OES,GL_MATRIX_INDEX_ARRAY_STRIDE_OES,GL_MATRIX_INDEX_ARRAY_TYPE_OES,GL_MATRIX_MODE,GL_MAX_CLIP_PLANES,GL_MAX_ELEMENTS_INDICES,GL_MAX_ELEMENTS_VERTICES,GL_MAX_LIGHTS,GL_MAX_MODELVIEW_STACK_DEPTH,GL_MAX_PALETTE_MATRICES_OES,GL_MAX_PROJECTION_STACK_DEPTH,GL_MAX_TEXTURE_SIZE,GL_MAX_TEXTURE_STACK_DEPTH,GL_MAX_TEXTURE_UNITS,GL_MAX_VERTEX_UNITS_OES,GL_MODELVIEW_STACK_DEPTH,GL_NORMAL_ARRAY_BUFFER_BINDING,GL_NORMAL_ARRAY_STRIDE,GL_NORMAL_ARRAY_TYPE,GL_NUM_COMPRESSED_TEXTURE_FORMATS,GL_PACK_ALIGNMENT,GL_PERSPECTIVE_CORRECTION_HINT,GL_POINT_SIZE,GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES,GL_POINT_SIZE_ARRAY_STRIDE_OES,GL_POINT_SIZE_ARRAY_TYPE_OES,GL_POINT_SMOOTH_HINT,GL_POLYGON_OFFSET_FACTOR,GL_POLYGON_OFFSET_UNITS,GL_PROJECTION_STACK_DEPTH,GL_RED_BITS,GL_SHADE_MODEL,GL_STENCIL_BITS,GL_STENCIL_CLEAR_VALUE,GL_STENCIL_FAIL,GL_STENCIL_FUNC,GL_STENCIL_PASS_DEPTH_FAIL,GL_STENCIL_PASS_DEPTH_PASS,GL_STENCIL_REF,GL_STENCIL_VALUE_MASK,GL_STENCIL_WRITEMASK,GL_SUBPIXEL_BITS,GL_TEXTURE_BINDING_2D,GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING,GL_TEXTURE_COORD_ARRAY_SIZE,GL_TEXTURE_COORD_ARRAY_STRIDE,GL_TEXTURE_COORD_ARRAY_TYPE,GL_TEXTURE_STACK_DEPTH,GL_UNPACK_ALIGNMENT,GL_VERTEX_ARRAY_BUFFER_BINDING,GL_VERTEX_ARRAY_SIZE,GL_VERTEX_ARRAY_STRIDE,GL_VERTEX_ARRAY_TYPE,GL_WEIGHT_ARRAY_BUFFER_BINDING_OES,GL_WEIGHT_ARRAY_SIZE_OES,GL_WEIGHT_ARRAY_STRIDE_OES,GL_WEIGHT_ARRAY_TYPE_OES ifcheck params 2 pname GL_ALIASED_POINT_SIZE_RANGE,GL_ALIASED_LINE_WIDTH_RANGE,GL_DEPTH_RANGE,GL_MAX_VIEWPORT_DIMS,GL_SMOOTH_LINE_WIDTH_RANGE,GL_SMOOTH_POINT_SIZE_RANGE ifcheck params 4 pname GL_COLOR_CLEAR_VALUE,GL_COLOR_WRITEMASK,GL_FOG_COLOR,GL_LIGHT_MODEL_AMBIENT,GL_SCISSOR_BOX,GL_VIEWPORT ifcheck params 16 pname GL_MODELVIEW_MATRIX,GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES,GL_PROJECTION_MATRIX,GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES,GL_TEXTURE_MATRIX,GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES ifcheck params getNumCompressedTextureFormats() pname GL_COMPRESSED_TEXTURE_FORMATS glGetLight ifcheck params 1 pname GL_SPOT_EXPONENT,GL_SPOT_CUTOFF,GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION ifcheck params 3 pname GL_SPOT_DIRECTION ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION glGetMaterial ifcheck params 1 pname GL_SHININESS ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION,GL_AMBIENT_AND_DIFFUSE +glGetRenderbufferParameterivOES check params 1 glGetTexEnv ifcheck params 1 pname GL_TEXTURE_ENV_MODE,GL_COMBINE_RGB,GL_COMBINE_ALPHA ifcheck params 4 pname GL_TEXTURE_ENV_COLOR +glGetTexGen ifcheck params 1 pname GL_TEXTURE_GEN_MODE ifcheck params 4 pname GL_OBJECT_PLANE,GL_EYE_PLANE glGetTexParameter check params 1 -glLightModel ifcheck params 1 pname GL_LIGHT_MODEL_TWO_SIDE ifcheck params 4 pname GL_LIGHT_MODEL_AMBIENT glLight ifcheck params 1 pname GL_SPOT_EXPONENT,GL_SPOT_CUTOFF,GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION ifcheck params 3 pname GL_SPOT_DIRECTION ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION +glLightModel ifcheck params 1 pname GL_LIGHT_MODEL_TWO_SIDE ifcheck params 4 pname GL_LIGHT_MODEL_AMBIENT glLoadMatrix check m 16 glMaterial ifcheck params 1 pname GL_SHININESS ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION,GL_AMBIENT_AND_DIFFUSE glMultMatrix check m 16 glPointParameter check params 1 +glQueryMatrixxOES check mantissa 16 check exponent 16 return -1 glTexEnv ifcheck params 1 pname GL_TEXTURE_ENV_MODE,GL_COMBINE_RGB,GL_COMBINE_ALPHA ifcheck params 4 pname GL_TEXTURE_ENV_COLOR glTexImage2D nullAllowed -glTexSubImage2D nullAllowed -glBufferData nullAllowed check data size -glBufferSubData check data size glTexParameter check params 1 -glQueryMatrixxOES check mantissa 16 check exponent 16 return -1 -glDrawTexfvOES check coords 5 -glDrawTexivOES check coords 5 -glDrawTexsvOES check coords 5 -glDrawTexxvOES check coords 5 -glDeleteFramebuffersOES check framebuffers n -glDeleteRenderbuffersOES check renderbuffers n -glGenFramebuffersOES check framebuffers n -glGenRenderbuffersOES check renderbuffers n -glGetBufferParameter check params 1 -glGetFramebufferAttachmentParameterivOES check params 1 -glGetRenderbufferParameterivOES check params 1 -glGetTexGen ifcheck params 1 pname GL_TEXTURE_GEN_MODE ifcheck params 4 pname GL_OBJECT_PLANE,GL_EYE_PLANE - +glTexSubImage2D nullAllowed diff --git a/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp b/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp index 290d102df6..5fda9f8e22 100644 --- a/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp +++ b/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp @@ -1,4 +1,3 @@ -/* ** Copyright 2012, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,7 +27,7 @@ #include <gui/Surface.h> #include <gui/GLConsumer.h> -#include <gui/SurfaceTextureClient.h> +#include <gui/Surface.h> #include <ui/ANativeObjectBase.h> diff --git a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp index a3d000ac90..906cd80fbb 100644 --- a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp +++ b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp @@ -34,7 +34,7 @@ not_valid_surface: goto exit; } - window = android::android_Surface_getNativeWindow(_env, win); + window = android::android_view_Surface_getNativeWindow(_env, win); if (window == NULL) goto not_valid_surface; @@ -112,7 +112,11 @@ not_valid_surface: goto exit; } glConsumer = android::SurfaceTexture_getSurfaceTexture(_env, win); - window = new android::SurfaceTextureClient(glConsumer); + + if (glConsumer == NULL) + goto not_valid_surface; + + window = new android::Surface(glConsumer->getBufferQueue()); if (window == NULL) goto not_valid_surface; diff --git a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl index e3aea76b04..9740235739 100644 --- a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl +++ b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl @@ -22,7 +22,7 @@ import android.app.AppGlobals; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.os.Build; -import android.os.UserId; +import android.os.UserHandle; import android.util.Log; import java.nio.Buffer; @@ -67,7 +67,7 @@ public class GLImpl implements GL10, GL10Ext, GL11, GL11Ext, GL11ExtensionPack { int version = 0; IPackageManager pm = AppGlobals.getPackageManager(); try { - ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0, UserId.myUserId()); + ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0, UserHandle.myUserId()); if (applicationInfo != null) { version = applicationInfo.targetSdkVersion; } diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index c28254f6f0..0f56f99d3b 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -35,7 +35,7 @@ const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER" // --------------------------------------------------------------------------- Client::Client(const sp<SurfaceFlinger>& flinger) - : mFlinger(flinger), mNameGenerator(1) + : mFlinger(flinger) { } @@ -54,12 +54,10 @@ status_t Client::initCheck() const { return NO_ERROR; } -size_t Client::attachLayer(const sp<LayerBaseClient>& layer) +void Client::attachLayer(const sp<IBinder>& handle, const sp<LayerBaseClient>& layer) { Mutex::Autolock _l(mLock); - size_t name = mNameGenerator++; - mLayers.add(name, layer); - return name; + mLayers.add(handle, layer); } void Client::detachLayer(const LayerBaseClient* layer) @@ -74,14 +72,14 @@ void Client::detachLayer(const LayerBaseClient* layer) } } } -sp<LayerBaseClient> Client::getLayerUser(int32_t i) const +sp<LayerBaseClient> Client::getLayerUser(const sp<IBinder>& handle) const { Mutex::Autolock _l(mLock); sp<LayerBaseClient> lbc; - wp<LayerBaseClient> layer(mLayers.valueFor(i)); + wp<LayerBaseClient> layer(mLayers.valueFor(handle)); if (layer != 0) { lbc = layer.promote(); - ALOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); + ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get()); } return lbc; } @@ -109,7 +107,6 @@ status_t Client::onTransact( sp<ISurface> Client::createSurface( - ISurfaceComposerClient::surface_data_t* params, const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) @@ -122,7 +119,6 @@ sp<ISurface> Client::createSurface( class MessageCreateLayer : public MessageBase { sp<ISurface> result; SurfaceFlinger* flinger; - ISurfaceComposerClient::surface_data_t* params; Client* client; const String8& name; uint32_t w, h; @@ -130,29 +126,28 @@ sp<ISurface> Client::createSurface( uint32_t flags; public: MessageCreateLayer(SurfaceFlinger* flinger, - ISurfaceComposerClient::surface_data_t* params, const String8& name, Client* client, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) - : flinger(flinger), params(params), client(client), name(name), + : flinger(flinger), client(client), name(name), w(w), h(h), format(format), flags(flags) { } sp<ISurface> getResult() const { return result; } virtual bool handler() { - result = flinger->createLayer(params, name, client, - w, h, format, flags); + result = flinger->createLayer(name, client, w, h, format, flags); return true; } }; sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), - params, name, this, w, h, format, flags); + name, this, w, h, format, flags); mFlinger->postMessageSync(msg); return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); } -status_t Client::destroySurface(SurfaceID sid) { - return mFlinger->onLayerRemoved(this, sid); + +status_t Client::destroySurface(const sp<IBinder>& handle) { + return mFlinger->onLayerRemoved(this, handle); } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h index d6c69312b6..e6a7165c73 100644 --- a/services/surfaceflinger/Client.h +++ b/services/surfaceflinger/Client.h @@ -44,20 +44,20 @@ public: status_t initCheck() const; // protected by SurfaceFlinger::mStateLock - size_t attachLayer(const sp<LayerBaseClient>& layer); + void attachLayer(const sp<IBinder>& handle, const sp<LayerBaseClient>& layer); void detachLayer(const LayerBaseClient* layer); - sp<LayerBaseClient> getLayerUser(int32_t i) const; + sp<LayerBaseClient> getLayerUser(const sp<IBinder>& handle) const; private: // ISurfaceComposerClient interface virtual sp<ISurface> createSurface( - surface_data_t* params, const String8& name, + const String8& name, uint32_t w, uint32_t h,PixelFormat format, uint32_t flags); - virtual status_t destroySurface(SurfaceID surfaceId); + virtual status_t destroySurface(const sp<IBinder>& handle); virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); @@ -66,8 +66,7 @@ private: sp<SurfaceFlinger> mFlinger; // protected by mLock - DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers; - size_t mNameGenerator; + DefaultKeyedVector< wp<IBinder>, wp<LayerBaseClient> > mLayers; // thread-safe mutable Mutex mLock; diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 19169a5515..9466944490 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -27,7 +27,7 @@ #include <ui/DisplayInfo.h> #include <ui/PixelFormat.h> -#include <gui/SurfaceTextureClient.h> +#include <gui/Surface.h> #include <GLES/gl.h> #include <EGL/egl.h> diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp index cccb29b777..7557e3fdc5 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp @@ -29,7 +29,7 @@ #include <EGL/egl.h> #include <hardware/hardware.h> -#include <gui/SurfaceTextureClient.h> +#include <gui/Surface.h> #include <gui/GraphicBufferAlloc.h> #include <ui/GraphicBuffer.h> diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index ead158ed8e..6f85f69031 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -529,7 +529,7 @@ status_t HWComposer::setFramebufferTarget(int32_t id, DisplayData& disp(mDisplayData[id]); if (!disp.framebufferTarget) { // this should never happen, but apparently eglCreateWindowSurface() - // triggers a SurfaceTextureClient::queueBuffer() on some + // triggers a Surface::queueBuffer() on some // devices (!?) -- log and ignore. ALOGE("HWComposer: framebufferTarget is null"); // CallStack stack; @@ -539,7 +539,7 @@ status_t HWComposer::setFramebufferTarget(int32_t id, } int acquireFenceFd = -1; - if (acquireFence != NULL) { + if (acquireFence->isValid()) { acquireFenceFd = acquireFence->dup(); } @@ -659,7 +659,7 @@ status_t HWComposer::commit() { for (size_t i=0 ; i<mNumDisplays ; i++) { DisplayData& disp(mDisplayData[i]); disp.lastDisplayFence = disp.lastRetireFence; - disp.lastRetireFence = NULL; + disp.lastRetireFence = Fence::NO_FENCE; if (disp.list) { if (disp.list->retireFenceFd != -1) { disp.lastRetireFence = new Fence(disp.list->retireFenceFd); @@ -725,9 +725,7 @@ int HWComposer::fbPost(int32_t id, if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { return setFramebufferTarget(id, acquireFence, buffer); } else { - if (acquireFence != NULL) { - acquireFence->waitForever(1000, "HWComposer::fbPost"); - } + acquireFence->waitForever(1000, "HWComposer::fbPost"); return mFbDev->post(mFbDev, buffer->handle); } } diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 99af85736d..1401154d3c 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -298,7 +298,7 @@ void Layer::setAcquireFence(const sp<const DisplayDevice>& hw, if (layer.getCompositionType() == HWC_OVERLAY) { sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); - if (fence.get()) { + if (fence->isValid()) { fenceFd = fence->dup(); if (fenceFd == -1) { ALOGW("failed to dup layer fence, skipping sync: %d", errno); diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp index 54c51bb5d4..dfdbf300fd 100644 --- a/services/surfaceflinger/LayerBase.cpp +++ b/services/surfaceflinger/LayerBase.cpp @@ -483,14 +483,11 @@ sp<Layer> LayerBase::getLayer() const { // --------------------------------------------------------------------------- -int32_t LayerBaseClient::sIdentity = 1; - LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, const sp<Client>& client) : LayerBase(flinger), mHasSurface(false), - mClientRef(client), - mIdentity(uint32_t(android_atomic_inc(&sIdentity))) + mClientRef(client) { } @@ -540,12 +537,8 @@ wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const { void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const { LayerBase::dump(result, buffer, SIZE); - sp<Client> client(mClientRef.promote()); - snprintf(buffer, SIZE, - " client=%p, identity=%u\n", - client.get(), getIdentity()); - + snprintf(buffer, SIZE, " client=%p\n", client.get()); result.append(buffer); } diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index 47473e7907..c2624df5d9 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -347,8 +347,6 @@ public: virtual const char* getTypeId() const { return "LayerBaseClient"; } - uint32_t getIdentity() const { return mIdentity; } - protected: virtual void dump(String8& result, char* scratch, size_t size) const; virtual void shortDump(String8& result, char* scratch, size_t size) const; @@ -379,9 +377,6 @@ private: wp<IBinder> mClientSurfaceBinder; const wp<Client> mClientRef; - // only read - const uint32_t mIdentity; - static int32_t sIdentity; }; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index caabf1d71c..09a1c59331 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -39,7 +39,7 @@ #include <gui/BufferQueue.h> #include <gui/GuiConfig.h> #include <gui/IDisplayEventConnection.h> -#include <gui/SurfaceTextureClient.h> +#include <gui/Surface.h> #include <gui/GraphicBufferAlloc.h> #include <ui/GraphicBufferAllocator.h> @@ -503,7 +503,7 @@ status_t SurfaceFlinger::readyToRun() wp<IBinder> token = mBuiltinDisplays[i]; sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i); - sp<SurfaceTextureClient> stc = new SurfaceTextureClient( + sp<Surface> stc = new Surface( static_cast< sp<IGraphicBufferProducer> >(fbs->getBufferQueue())); sp<DisplayDevice> hw = new DisplayDevice(this, type, isSecure, token, stc, fbs, mEGLConfig); @@ -1182,7 +1182,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) const DisplayDeviceState& state(curr[i]); sp<FramebufferSurface> fbs; - sp<SurfaceTextureClient> stc; + sp<Surface> stc; if (!state.isVirtualDisplay()) { ALOGE_IF(state.surface!=NULL, @@ -1193,12 +1193,12 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) // for supported (by hwc) displays we provide our // own rendering surface fbs = new FramebufferSurface(*mHwc, state.type); - stc = new SurfaceTextureClient( + stc = new Surface( static_cast< sp<IGraphicBufferProducer> >( fbs->getBufferQueue())); } else { if (state.surface != NULL) { - stc = new SurfaceTextureClient(state.surface); + stc = new Surface(state.surface); } } @@ -1682,17 +1682,16 @@ void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, } } -ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, +void SurfaceFlinger::addClientLayer(const sp<Client>& client, + const sp<IBinder>& handle, const sp<LayerBaseClient>& lbc) { // attach this layer to the client - size_t name = client->attachLayer(lbc); + client->attachLayer(handle, lbc); // add this layer to the current state list Mutex::Autolock _l(mStateLock); mCurrentState.layersSortedByZ.add(lbc); - - return ssize_t(name); } status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) @@ -1933,10 +1932,9 @@ uint32_t SurfaceFlinger::setClientStateLocked( } sp<ISurface> SurfaceFlinger::createLayer( - ISurfaceComposerClient::surface_data_t* params, const String8& name, const sp<Client>& client, - uint32_t w, uint32_t h, PixelFormat format, + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { sp<LayerBaseClient> layer; @@ -1965,11 +1963,9 @@ sp<ISurface> SurfaceFlinger::createLayer( if (layer != 0) { layer->initStates(w, h, flags); layer->setName(name); - ssize_t token = addClientLayer(client, layer); surfaceHandle = layer->getSurface(); if (surfaceHandle != 0) { - params->token = token; - params->identity = layer->getIdentity(); + addClientLayer(client, surfaceHandle->asBinder(), layer); } setTransactionFlags(eTransactionNeeded); } @@ -2027,7 +2023,7 @@ sp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer( return layer; } -status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid) +status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) { /* * called by the window manager, when a surface should be marked for @@ -2040,7 +2036,7 @@ status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid) status_t err = NAME_NOT_FOUND; Mutex::Autolock _l(mStateLock); - sp<LayerBaseClient> layer = client->getLayerUser(sid); + sp<LayerBaseClient> layer = client->getLayerUser(handle); if (layer != 0) { err = purgatorizeLayer_l(layer); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 72dd6524ae..e67f3f1873 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -64,7 +64,7 @@ class LayerBase; class LayerBaseClient; class LayerDim; class LayerScreenshot; -class SurfaceTextureClient; +class Surface; // --------------------------------------------------------------------------- @@ -267,8 +267,7 @@ private: /* ------------------------------------------------------------------------ * Layer management */ - sp<ISurface> createLayer(ISurfaceComposerClient::surface_data_t* params, - const String8& name, const sp<Client>& client, + sp<ISurface> createLayer(const String8& name, const sp<Client>& client, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); sp<Layer> createNormalLayer(const sp<Client>& client, @@ -284,7 +283,7 @@ private: // 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, SurfaceID sid); + status_t onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle); // called when all clients have released all their references to // this layer meaning it is entirely safe to destroy all @@ -295,7 +294,7 @@ private: status_t removeLayer(const sp<LayerBase>& layer); // add a layer to SurfaceFlinger - ssize_t addClientLayer(const sp<Client>& client, + void addClientLayer(const sp<Client>& client, const sp<IBinder>& handle, const sp<LayerBaseClient>& lbc); status_t removeLayer_l(const sp<LayerBase>& layer); diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp index dc9089e3d0..e427072442 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp +++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp @@ -15,6 +15,7 @@ */ #define ATRACE_TAG ATRACE_TAG_GRAPHICS +//#define LOG_NDEBUG 0 #include "SurfaceFlingerConsumer.h" diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 0592c5b4bb..4d363c8a00 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -31,14 +31,14 @@ namespace android { // Fill an RGBA_8888 formatted surface with a single color. static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc, uint8_t r, uint8_t g, uint8_t b) { - Surface::SurfaceInfo info; + ANativeWindow_Buffer outBuffer; sp<Surface> s = sc->getSurface(); ASSERT_TRUE(s != NULL); - ASSERT_EQ(NO_ERROR, s->lock(&info)); - uint8_t* img = reinterpret_cast<uint8_t*>(info.bits); - for (uint32_t y = 0; y < info.h; y++) { - for (uint32_t x = 0; x < info.w; x++) { - uint8_t* pixel = img + (4 * (y*info.s + x)); + ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, NULL)); + uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits); + for (uint32_t y = 0; y < outBuffer.height; y++) { + for (uint32_t x = 0; x < outBuffer.width; x++) { + uint8_t* pixel = img + (4 * (y*outBuffer.stride + x)); pixel[0] = r; pixel[1] = g; pixel[2] = b; diff --git a/services/surfaceflinger/tests/resize/resize.cpp b/services/surfaceflinger/tests/resize/resize.cpp index d61ea70ac7..8b051e8114 100644 --- a/services/surfaceflinger/tests/resize/resize.cpp +++ b/services/surfaceflinger/tests/resize/resize.cpp @@ -38,26 +38,27 @@ int main(int argc, char** argv) // create a client to surfaceflinger sp<SurfaceComposerClient> client = new SurfaceComposerClient(); - sp<Surface> surface = client->createSurface(String8("resize"), + sp<SurfaceControl> surfaceControl = client->createSurface(String8("resize"), 160, 240, PIXEL_FORMAT_RGB_565, 0); + sp<Surface> surface = surfaceControl->getSurface(); SurfaceComposerClient::openGlobalTransaction(); - surface->setLayer(100000); + surfaceControl->setLayer(100000); SurfaceComposerClient::closeGlobalTransaction(); - Surface::SurfaceInfo info; - surface->lock(&info); - ssize_t bpr = info.s * bytesPerPixel(info.format); - android_memset16((uint16_t*)info.bits, 0xF800, bpr*info.h); + ANativeWindow_Buffer outBuffer; + surface->lock(&outBuffer, NULL); + ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format); + android_memset16((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height); surface->unlockAndPost(); - surface->lock(&info); - android_memset16((uint16_t*)info.bits, 0x07E0, bpr*info.h); + surface->lock(&outBuffer); + android_memset16((uint16_t*)outBuffer.bits, 0x07E0, bpr*outBuffer.height); surface->unlockAndPost(); SurfaceComposerClient::openGlobalTransaction(); - surface->setSize(320, 240); + surfaceControl->setSize(320, 240); SurfaceComposerClient::closeGlobalTransaction(); |