From e3c697fb929c856b59fa56a8e05a2a7eba187c3d Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 14 Feb 2013 17:11:02 -0800 Subject: [PATCH] Refactoring: Rename SurfaceTextureClient to Surface Change-Id: Ibed34175ae273608393aaa5f0a7df207dc40d709 --- cmds/flatland/GLHelper.cpp | 2 +- cmds/flatland/GLHelper.h | 2 +- cmds/flatland/Main.cpp | 2 +- include/gui/IGraphicBufferProducer.h | 4 +- include/gui/Surface.h | 299 +++-- include/gui/SurfaceComposerClient.h | 2 +- include/gui/SurfaceControl.h | 101 ++ include/gui/SurfaceTextureClient.h | 234 ---- include/ui/GraphicBuffer.h | 2 +- libs/gui/Android.mk | 2 +- libs/gui/Surface.cpp | 1076 ++++++++++++----- libs/gui/SurfaceComposerClient.cpp | 1 + libs/gui/SurfaceControl.cpp | 194 +++ libs/gui/SurfaceTextureClient.cpp | 846 ------------- libs/gui/tests/CpuConsumer_test.cpp | 6 +- libs/gui/tests/SurfaceTextureClient_test.cpp | 10 +- libs/gui/tests/SurfaceTexture_test.cpp | 5 +- opengl/tests/EGLTest/EGL_test.cpp | 4 +- opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp | 2 +- .../stubs/egl/eglCreateWindowSurface.cpp | 2 +- services/surfaceflinger/DisplayDevice.cpp | 2 +- .../DisplayHardware/FramebufferSurface.cpp | 2 +- .../DisplayHardware/HWComposer.cpp | 2 +- services/surfaceflinger/SurfaceFlinger.cpp | 10 +- services/surfaceflinger/SurfaceFlinger.h | 2 +- .../surfaceflinger/tests/Transaction_test.cpp | 12 +- .../surfaceflinger/tests/resize/resize.cpp | 19 +- 27 files changed, 1311 insertions(+), 1534 deletions(-) create mode 100644 include/gui/SurfaceControl.h delete mode 100644 include/gui/SurfaceTextureClient.h create mode 100644 libs/gui/SurfaceControl.cpp delete mode 100644 libs/gui/SurfaceTextureClient.cpp diff --git a/cmds/flatland/GLHelper.cpp b/cmds/flatland/GLHelper.cpp index 364789759..4f7697f4a 100644 --- a/cmds/flatland/GLHelper.cpp +++ b/cmds/flatland/GLHelper.cpp @@ -205,7 +205,7 @@ bool GLHelper::createNamedSurfaceTexture(GLuint name, uint32_t w, uint32_t h, glc->setDefaultMaxBufferCount(3); glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER); - sp anw = new SurfaceTextureClient(bq); + sp 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 19fdff986..73413740c 100644 --- a/cmds/flatland/GLHelper.h +++ b/cmds/flatland/GLHelper.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/cmds/flatland/Main.cpp b/cmds/flatland/Main.cpp index 45f414e4f..a65052ed5 100644 --- a/cmds/flatland/Main.cpp +++ b/cmds/flatland/Main.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h index f230b8d64..a3e258df3 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/Surface.h b/include/gui/Surface.h index ec75d4e9f..4300a0fff 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,155 +17,224 @@ #ifndef ANDROID_GUI_SURFACE_H #define ANDROID_GUI_SURFACE_H -#include -#include +#include +#include +#include -#include -#include -#include - -#include +#include #include -#include -#include -#include +#include +#include +#include + +struct ANativeWindow_Buffer; namespace android { -// --------------------------------------------------------------------------- - -class IGraphicBufferProducer; -class Surface; -class SurfaceComposerClient; - -// --------------------------------------------------------------------------- - -class SurfaceControl : public RefBase +/* + * 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 + * 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 ANativeObjectBase { public: - static bool isValid(const sp& surface) { - return (surface != 0) && surface->isValid(); - } - bool isValid() { - return mSurface!=0 && mClient!=0; - } - static bool isSameSurface( - const sp& lhs, const sp& rhs); - - // 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& control, Parcel* parcel); + Surface(const sp& bufferProducer); - sp getSurface() const; + sp getIGraphicBufferProducer() const; + + static status_t writeToParcel(const sp& surface, Parcel* parcel); + static sp readFromParcel(const Parcel& data); + + // FIXME: temporary for source compatibility... + sp getISurfaceTexture() const { + return getIGraphicBufferProducer(); + } + +protected: + Surface(); + virtual ~Surface(); + void setIGraphicBufferProducer(const sp& bufferProducer); private: // can't be copied - SurfaceControl& operator = (SurfaceControl& rhs); - SurfaceControl(const SurfaceControl& rhs); + Surface& operator = (const Surface& rhs); + Surface(const Surface& rhs); + void init(); - friend class SurfaceComposerClient; - friend class Surface; + // 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); - SurfaceControl( - const sp& client, - const sp& surface); + 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); - ~SurfaceControl(); + 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); - status_t validate() const; - void destroy(); - - sp mClient; - sp mSurface; - mutable Mutex mLock; - mutable sp mSurfaceData; -}; - -// --------------------------------------------------------------------------- +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); -/* - * This is a small wrapper around SurfaceTextureClient. - * - * TODO: rename and/or merge with STC. - */ -class Surface : public SurfaceTextureClient -{ public: - struct SurfaceInfo { - uint32_t w; - uint32_t h; - uint32_t s; - uint32_t usage; - PixelFormat format; - void* bits; - uint32_t reserved[2]; + virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); + virtual int unlockAndPost(); + +protected: + 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 buffer; + Region dirtyRegion; }; - explicit Surface(const sp& bp); + // 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 mGraphicBufferProducer; - static status_t writeToParcel(const sp& control, Parcel* parcel); + // 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]; - static sp readFromParcel(const Parcel& data); - static bool isValid(const sp& surface) { - return (surface != 0) && surface->isValid(); - } + // mReqWidth is the buffer width that will be requested at the next dequeue + // operation. It is initialized to 1. + uint32_t mReqWidth; - bool isValid(); - uint32_t getIdentity() const { return mIdentity; } - sp getSurfaceTexture(); // TODO: rename this + // mReqHeight is the buffer height that will be requested at the next + // dequeue operation. It is initialized to 1. + uint32_t mReqHeight; - // the lock/unlock APIs must be used from the same thread - status_t lock(SurfaceInfo* info, Region* dirty = NULL); - status_t unlockAndPost(); + // 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; - sp asBinder() const; + // 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; -private: - // this is just to be able to write some unit tests - friend class Test; - friend class SurfaceControl; + // 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; - // can't be copied - Surface& operator = (Surface& rhs); - Surface(const Surface& rhs); + // mCrop is the crop rectangle that will be used for the next buffer + // that gets queued. It is set by calling setCrop. + Rect mCrop; - explicit Surface(const sp& control); - Surface(const Parcel& data, const sp& ref); - ~Surface(); + // mScalingMode is the scaling mode that will be used for the next + // buffers that get queued. It is set by calling setScalingMode. + int mScalingMode; - /* - * private stuff... - */ - void init(const sp& bufferProducer); + // 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; - static void cleanCachedSurfacesLocked(); + // mDefaultWidth is default width of the buffers, regardless of the + // native_window_set_buffers_dimensions call. + uint32_t mDefaultWidth; - virtual int query(int what, int* value) const; + // mDefaultHeight is default height of the buffers, regardless of the + // native_window_set_buffers_dimensions call. + uint32_t mDefaultHeight; - // constants - sp mSurface; - uint32_t mIdentity; + // 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; - // A cache of Surface objects that have been deserialized into this process. - static Mutex sCachedSurfacesLock; - static DefaultKeyedVector, wp > sCachedSurfaces; + // 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 mLockedBuffer; + sp 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 e0761b955..9e4d6fc30 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -30,7 +30,7 @@ #include -#include +#include namespace android { diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h new file mode 100644 index 000000000..f70888ddf --- /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 +#include + +#include +#include +#include + +#include +#include + +#include +#include + +namespace android { + +// --------------------------------------------------------------------------- + +class IGraphicBufferProducer; +class Surface; +class SurfaceComposerClient; + +// --------------------------------------------------------------------------- + +class SurfaceControl : public RefBase +{ +public: + static bool isValid(const sp& surface) { + return (surface != 0) && surface->isValid(); + } + bool isValid() { + return mSurface!=0 && mClient!=0; + } + static bool isSameSurface( + const sp& lhs, const sp& rhs); + + // 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& control, Parcel* parcel); + + sp getSurface() const; + +private: + // can't be copied + SurfaceControl& operator = (SurfaceControl& rhs); + SurfaceControl(const SurfaceControl& rhs); + + friend class SurfaceComposerClient; + friend class Surface; + + SurfaceControl( + const sp& client, + const sp& surface); + + ~SurfaceControl(); + + status_t validate() const; + void destroy(); + + sp mClient; + sp mSurface; + sp mGraphicBufferProducer; + mutable Mutex mLock; + mutable sp 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 6f0982192..000000000 --- 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 -#include -#include - -#include -#include - -#include -#include -#include - -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 -{ -public: - - SurfaceTextureClient(const sp& bufferProducer); - - sp getISurfaceTexture() const; // TODO: rename - -protected: - SurfaceTextureClient(); - virtual ~SurfaceTextureClient(); - void setISurfaceTexture(const sp& 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 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 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 mLockedBuffer; - sp mPostedBuffer; - bool mConnectedToCpu; - - // must be accessed from lock/unlock thread only - Region mDirtyRegion; -}; - -}; // namespace android - -#endif // ANDROID_GUI_SURFACETEXTURECLIENT_H diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h index f318cd899..d3839ea07 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(const GraphicBuffer& rhs); GraphicBuffer& operator = (const GraphicBuffer& rhs); diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk index b1aeb3288..544b66407 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/Surface.cpp b/libs/gui/Surface.cpp index 81fc019ea..410ad5da9 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,359 +15,851 @@ */ #define LOG_TAG "Surface" - -#include -#include -#include -#include +#define ATRACE_TAG ATRACE_TAG_GRAPHICS +//#define LOG_NDEBUG 0 #include -#include -#include +#include + #include -#include +#include -#include +#include -#include -#include -#include - -#include #include -#include #include -#include +#include +#include + +#include namespace android { -// ============================================================================ -// SurfaceControl -// ============================================================================ - -SurfaceControl::SurfaceControl( - const sp& client, - const sp& surface) - : mClient(client) +Surface::Surface( + const sp& bufferProducer) { - if (surface != 0) { - mSurface = surface->asBinder(); + Surface::init(); + Surface::setIGraphicBufferProducer(bufferProducer); +} + +Surface::Surface() { + Surface::init(); +} + +Surface::~Surface() { + if (mConnectedToCpu) { + Surface::disconnect(NATIVE_WINDOW_API_CPU); } } - -SurfaceControl::~SurfaceControl() -{ - destroy(); + +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(ANativeWindow::minSwapInterval) = 0; + const_cast(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 SurfaceControl::destroy() +void Surface::setIGraphicBufferProducer( + const sp& bufferProducer) { - if (isValid()) { - mClient->destroySurface(mSurface); + mGraphicBufferProducer = bufferProducer; +} + +sp 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(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; } - // 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(); + *buffer = buf; + return result; } -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(); +int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer) { + Surface* c = getSelf(window); + return c->cancelBuffer(buffer, -1); } -bool SurfaceControl::isSameSurface( - const sp& lhs, const sp& rhs) -{ - if (lhs == 0 || rhs == 0) - return false; - return lhs->mSurface == rhs->mSurface; +int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer) { + Surface* c = getSelf(window); + return c->lockBuffer_DEPRECATED(buffer); } -status_t SurfaceControl::setLayerStack(int32_t layerStack) { - status_t err = validate(); - if (err < 0) return err; - const sp& 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& client(mClient); - return client->setLayer(mSurface, layer); -} -status_t SurfaceControl::setPosition(int32_t x, int32_t y) { - status_t err = validate(); - if (err < 0) return err; - const sp& 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& client(mClient); - return client->setSize(mSurface, w, h); -} -status_t SurfaceControl::hide() { - status_t err = validate(); - if (err < 0) return err; - const sp& client(mClient); - return client->hide(mSurface); -} -status_t SurfaceControl::show() { - status_t err = validate(); - if (err < 0) return err; - const sp& 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& 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& client(mClient); - return client->setTransparentRegionHint(mSurface, transparent); -} -status_t SurfaceControl::setAlpha(float alpha) { - status_t err = validate(); - if (err < 0) return err; - const sp& 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& 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& client(mClient); - return client->setCrop(mSurface, crop); +int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer) { + Surface* c = getSelf(window); + return c->queueBuffer(buffer, -1); } -status_t SurfaceControl::validate() const -{ - if (mSurface==0 || mClient==0) { - ALOGE("invalid ISurface (%p) or client (%p)", - mSurface.get(), mClient.get()); - return NO_INIT; +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; + 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; } - return NO_ERROR; -} - -status_t SurfaceControl::writeSurfaceToParcel( - const sp& control, Parcel* parcel) -{ - sp sur; - if (SurfaceControl::isValid(control)) { - sur = control->mSurface; - } - parcel->writeStrongBinder(sur); - parcel->writeStrongBinder(NULL); // NULL IGraphicBufferProducer in this case. - return NO_ERROR; -} - -sp SurfaceControl::getSurface() const -{ - Mutex::Autolock _l(mLock); - if (mSurfaceData == 0) { - sp surface_control(const_cast(this)); - mSurfaceData = new Surface(surface_control); - } - return mSurfaceData; -} - -// ============================================================================ -// Surface -// ============================================================================ - -Surface::Surface(const sp& surface) - : SurfaceTextureClient() -{ - mSurface = interface_cast(surface->mSurface); - sp st; - if (mSurface != NULL) { - st = mSurface->getSurfaceTexture(); - } - init(st); -} - -Surface::Surface(const Parcel& parcel, const sp& ref) - : SurfaceTextureClient() -{ - mSurface = interface_cast(ref); - sp st_binder(parcel.readStrongBinder()); - sp st; - if (st_binder != NULL) { - st = interface_cast(st_binder); - } else if (mSurface != NULL) { - st = mSurface->getSurfaceTexture(); - } - init(st); -} - -Surface::Surface(const sp& st) - : SurfaceTextureClient(), - mSurface(NULL) -{ - init(st); -} - -status_t Surface::writeToParcel( - const sp& surface, Parcel* parcel) -{ - sp sur; - sp st; - uint32_t identity = 0; - if (Surface::isValid(surface)) { - sur = surface->mSurface; - st = surface->getISurfaceTexture(); - } 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 ", - surface->mSurface.get(), surface->getISurfaceTexture().get()); + sp& gbuf(mSlots[buf].buffer); + if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) { + freeAllBuffers(); } - parcel->writeStrongBinder(sur != NULL ? sur->asBinder() : NULL); - parcel->writeStrongBinder(st != NULL ? st->asBinder() : NULL); - return NO_ERROR; + 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; + } + } -} - -Mutex Surface::sCachedSurfacesLock; -DefaultKeyedVector, wp > Surface::sCachedSurfaces; - -sp Surface::readFromParcel(const Parcel& data) { - Mutex::Autolock _l(sCachedSurfacesLock); - sp binder(data.readStrongBinder()); - sp surface = sCachedSurfaces.valueFor(binder).promote(); - if (surface == 0) { - surface = new Surface(data, binder); - sCachedSurfaces.add(binder, surface); + 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 { - // The Surface was found in the cache, but we still should clear any - // remaining data from the parcel. - data.readStrongBinder(); // IGraphicBufferProducer - data.readInt32(); // identity + *fenceFd = -1; } - if (surface->mSurface == NULL && surface->getISurfaceTexture() == NULL) { - surface = 0; - } - cleanCachedSurfacesLocked(); - return surface; + + *buffer = gbuf.get(); + return OK; } -// 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 s(sCachedSurfaces.valueAt(i)); - if (s == 0 || s.promote() == 0) { - sCachedSurfaces.removeItemsAt(i); +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(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; } } + ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle); + return BAD_VALUE; } -void Surface::init(const sp& bufferProducer) -{ - 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); - } +int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer) { + ALOGV("Surface::lockBuffer"); + Mutex::Autolock lock(mMutex); + return OK; +} - // TODO: the display metrics should come from the display manager - DisplayInfo dinfo; - sp display = SurfaceComposerClient::getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain); - SurfaceComposerClient::getDisplayInfo(display, &dinfo); - const_cast(ANativeWindow::xdpi) = dinfo.xdpi; - const_cast(ANativeWindow::ydpi) = dinfo.ydpi; - const_cast(ANativeWindow::flags) = 0; +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() -{ - // 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(); -} -bool Surface::isValid() { - return getISurfaceTexture() != NULL; -} + // Make sure the crop rectangle is entirely inside the buffer. + Rect crop; + mCrop.intersect(Rect(buffer->width, buffer->height), &crop); -sp Surface::getSurfaceTexture() { - return getISurfaceTexture(); -} + sp 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); + } + uint32_t numPendingBuffers = 0; + output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, + &numPendingBuffers); -sp Surface::asBinder() const { - return mSurface!=0 ? mSurface->asBinder() : 0; -} + mConsumerRunningBehind = (numPendingBuffers >= 2); -// ---------------------------------------------------------------------------- + return err; +} int Surface::query(int what, int* value) const { - switch (what) { - case NATIVE_WINDOW_CONCRETE_TYPE: - *value = NATIVE_WINDOW_SURFACE; - return NO_ERROR; + 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 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 SurfaceTextureClient::query(what, value); + return mGraphicBufferProducer->query(what, value); } -// ---------------------------------------------------------------------------- +int Surface::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; +} -status_t Surface::lock(SurfaceInfo* other, Region* inOutDirtyRegion) { - ANativeWindow_Buffer outBuffer; +int Surface::dispatchConnect(va_list args) { + int api = va_arg(args, int); + return connect(api); +} - ARect temp; - ARect* inOutDirtyBounds = NULL; - if (inOutDirtyRegion) { - temp = inOutDirtyRegion->getBounds(); - inOutDirtyBounds = &temp; +int Surface::dispatchDisconnect(va_list args) { + int api = va_arg(args, int); + return disconnect(api); +} + +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)); +} + +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); +} + +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); +} + +int Surface::dispatchSetBuffersFormat(va_list args) { + int f = va_arg(args, int); + return setBuffersFormat(f); +} + +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 (!err && api == NATIVE_WINDOW_API_CPU) { + mConnectedToCpu = true; + } + return err; +} + +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; +} + +int Surface::setUsage(uint32_t reqUsage) +{ + ALOGV("Surface::setUsage"); + Mutex::Autolock lock(mMutex); + mReqUsage = reqUsage; + return OK; +} + +int Surface::setCrop(Rect const* rect) +{ + ATRACE_CALL(); + + Rect realRect; + if (rect == NULL || rect->isEmpty()) { + realRect.clear(); + } else { + realRect = *rect; } - status_t err = SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds); + 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; +} + +int Surface::setBufferCount(int bufferCount) +{ + 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) { - 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; - } - - if (inOutDirtyRegion) { - inOutDirtyRegion->set( static_cast(temp) ); + freeAllBuffers(); } return err; } -status_t Surface::unlockAndPost() { - return SurfaceTextureClient::unlockAndPost(); +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; +} + +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; +} + +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; + } + + 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; + } +} + +// ---------------------------------------------------------------------- +// the lock/unlock APIs must be used from the same thread + +static status_t copyBlt( + const sp& dst, + const sp& 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 Surface::writeToParcel( + const sp& surface, Parcel* parcel) { + sp bp; + if (surface != NULL) { + bp = surface->mGraphicBufferProducer; + } + return parcel->writeStrongBinder(bp->asBinder()); +} + +sp Surface::readFromParcel(const Parcel& data) { + sp binder(data.readStrongBinder()); + sp bp(interface_cast(binder)); + return new Surface(bp); +} + +// ---------------------------------------------------------------------------- + +status_t Surface::lock( + ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds) +{ + if (mLockedBuffer != 0) { + ALOGE("Surface::lock failed, already locked"); + return INVALID_OPERATION; + } + + 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 backBuffer(GraphicBuffer::getSelf(out)); + sp 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(*inOutDirtyBounds)); + newDirtyRegion.andSelf(bounds); + } else { + newDirtyRegion.set(bounds); + } + + // figure out if we can copy the frontbuffer back + const sp& 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= 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() +{ + 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 0bafc925d..e8e208f12 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -31,6 +31,7 @@ #include +#include #include #include #include diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp new file mode 100644 index 000000000..ef52269b0 --- /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 +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android { + +// ============================================================================ +// SurfaceControl +// ============================================================================ + +SurfaceControl::SurfaceControl( + const sp& client, + const sp& 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& lhs, const sp& 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& 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& client(mClient); + return client->setLayer(mSurface, layer); +} +status_t SurfaceControl::setPosition(int32_t x, int32_t y) { + status_t err = validate(); + if (err < 0) return err; + const sp& 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& client(mClient); + return client->setSize(mSurface, w, h); +} +status_t SurfaceControl::hide() { + status_t err = validate(); + if (err < 0) return err; + const sp& client(mClient); + return client->hide(mSurface); +} +status_t SurfaceControl::show() { + status_t err = validate(); + if (err < 0) return err; + const sp& 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& 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& client(mClient); + return client->setTransparentRegionHint(mSurface, transparent); +} +status_t SurfaceControl::setAlpha(float alpha) { + status_t err = validate(); + if (err < 0) return err; + const sp& 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& 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& 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& control, Parcel* parcel) +{ + sp bp; + if (control != NULL) { + bp = control->mGraphicBufferProducer; + } + return parcel->writeStrongBinder(bp->asBinder()); +} + +sp 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 5ed2e3815..000000000 --- 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 - -#include -#include - -#include - -#include -#include -#include -#include - -#include - -namespace android { - -SurfaceTextureClient::SurfaceTextureClient( - const sp& 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(ANativeWindow::minSwapInterval) = 0; - const_cast(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& bufferProducer) -{ - mSurfaceTexture = bufferProducer; -} - -sp 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(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; - 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& 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->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; -} - -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(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); - 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(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); - 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 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)); -} - -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& dst, - const sp& 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 backBuffer(GraphicBuffer::getSelf(out)); - sp 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(*inOutDirtyBounds)); - newDirtyRegion.andSelf(bounds); - } else { - newDirtyRegion.set(bounds); - } - - // figure out if we can copy the frontbuffer back - const sp& 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= 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/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp index 72a36bff7..12ae19cce 100644 --- a/libs/gui/tests/CpuConsumer_test.cpp +++ b/libs/gui/tests/CpuConsumer_test.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -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 mCC; - sp mSTC; + sp mSTC; sp mANW; }; diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp index 2df83a08d..58ae1708e 100644 --- a/libs/gui/tests/SurfaceTextureClient_test.cpp +++ b/libs/gui/tests/SurfaceTextureClient_test.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include @@ -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 mST; - sp mSTC; + sp mSTC; sp mANW; EGLDisplay mEglDisplay; @@ -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 st(new GLConsumer(i)); - sp stc(new SurfaceTextureClient(st->getBufferQueue())); + sp stc(new Surface(st->getBufferQueue())); mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig, static_cast(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 9062f84c4..fbaf6aabb 100644 --- a/libs/gui/tests/SurfaceTexture_test.cpp +++ b/libs/gui/tests/SurfaceTexture_test.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -383,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()); @@ -574,7 +573,7 @@ protected: }; sp mST; - sp mSTC; + sp mSTC; sp mANW; sp mTextureRenderer; sp mFW; diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp index ec433fb08..c0daba2e6 100644 --- a/opengl/tests/EGLTest/EGL_test.cpp +++ b/opengl/tests/EGLTest/EGL_test.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include @@ -104,7 +104,7 @@ TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) { // Create a EGLSurface sp bq = new BufferQueue(); bq->consumerConnect(new DummyConsumer()); - sp mSTC = new SurfaceTextureClient(static_cast >( bq)); + sp mSTC = new Surface(static_cast >( bq)); sp mANW = mSTC; EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, diff --git a/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp b/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp index 290d102df..54de1e7b7 100644 --- a/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp +++ b/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp @@ -28,7 +28,7 @@ #include #include -#include +#include #include diff --git a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp index a3d000ac9..14213b677 100644 --- a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp +++ b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp @@ -112,7 +112,7 @@ not_valid_surface: goto exit; } glConsumer = android::SurfaceTexture_getSurfaceTexture(_env, win); - window = new android::SurfaceTextureClient(glConsumer); + window = new android::Surface(glConsumer); if (window == NULL) goto not_valid_surface; diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 19169a551..946694449 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp index cccb29b77..7557e3fdc 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 7a24d4c24..6f85f6903 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; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index efcef92b6..09a1c5933 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include @@ -503,7 +503,7 @@ status_t SurfaceFlinger::readyToRun() wp token = mBuiltinDisplays[i]; sp fbs = new FramebufferSurface(*mHwc, i); - sp stc = new SurfaceTextureClient( + sp stc = new Surface( static_cast< sp >(fbs->getBufferQueue())); sp 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 fbs; - sp stc; + sp 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 >( fbs->getBufferQueue())); } else { if (state.surface != NULL) { - stc = new SurfaceTextureClient(state.surface); + stc = new Surface(state.surface); } } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 3cda6c08a..e67f3f187 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; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 0592c5b4b..4d363c8a0 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& sc, uint8_t r, uint8_t g, uint8_t b) { - Surface::SurfaceInfo info; + ANativeWindow_Buffer outBuffer; sp s = sc->getSurface(); ASSERT_TRUE(s != NULL); - ASSERT_EQ(NO_ERROR, s->lock(&info)); - uint8_t* img = reinterpret_cast(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(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 d61ea70ac..8b051e811 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 client = new SurfaceComposerClient(); - sp surface = client->createSurface(String8("resize"), + sp surfaceControl = client->createSurface(String8("resize"), 160, 240, PIXEL_FORMAT_RGB_565, 0); + sp 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();