| /* |
| * 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_SURFACE_FLINGER_H |
| #define ANDROID_SURFACE_FLINGER_H |
| |
| #include <stdint.h> |
| #include <sys/types.h> |
| |
| #include <utils/SortedVector.h> |
| #include <utils/KeyedVector.h> |
| #include <utils/threads.h> |
| #include <utils/Atomic.h> |
| #include <utils/Errors.h> |
| #include <utils/RefBase.h> |
| |
| #include <binder/IMemory.h> |
| #include <binder/Permission.h> |
| |
| #include <ui/PixelFormat.h> |
| #include <ui/ISurfaceComposer.h> |
| #include <ui/ISurfaceFlingerClient.h> |
| |
| #include <private/ui/SharedBufferStack.h> |
| #include <private/ui/LayerState.h> |
| |
| #include "Barrier.h" |
| #include "Layer.h" |
| #include "Tokenizer.h" |
| |
| #include "MessageQueue.h" |
| |
| struct copybit_device_t; |
| struct overlay_device_t; |
| |
| namespace android { |
| |
| // --------------------------------------------------------------------------- |
| |
| class Client; |
| class BClient; |
| class DisplayHardware; |
| class FreezeLock; |
| class Layer; |
| class LayerBuffer; |
| |
| typedef int32_t ClientID; |
| |
| #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) |
| #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) |
| |
| // --------------------------------------------------------------------------- |
| |
| class Client : public RefBase |
| { |
| public: |
| Client(ClientID cid, const sp<SurfaceFlinger>& flinger); |
| ~Client(); |
| |
| int32_t generateId(int pid); |
| void free(int32_t id); |
| status_t bindLayer(const sp<LayerBaseClient>& layer, int32_t id); |
| |
| inline bool isValid(int32_t i) const; |
| sp<LayerBaseClient> getLayerUser(int32_t i) const; |
| void dump(const char* what); |
| |
| const Vector< wp<LayerBaseClient> >& getLayers() const { |
| return mLayers; |
| } |
| |
| const sp<IMemoryHeap>& getControlBlockMemory() const { |
| return mCblkHeap; |
| } |
| |
| // pointer to this client's control block |
| SharedClient* ctrlblk; |
| ClientID cid; |
| |
| |
| private: |
| int getClientPid() const { return mPid; } |
| |
| int mPid; |
| uint32_t mBitmap; |
| SortedVector<uint8_t> mInUse; |
| Vector< wp<LayerBaseClient> > mLayers; |
| sp<IMemoryHeap> mCblkHeap; |
| sp<SurfaceFlinger> mFlinger; |
| }; |
| |
| // --------------------------------------------------------------------------- |
| |
| class GraphicPlane |
| { |
| public: |
| static status_t orientationToTransfrom(int orientation, int w, int h, |
| Transform* tr); |
| |
| GraphicPlane(); |
| ~GraphicPlane(); |
| |
| bool initialized() const; |
| |
| void setDisplayHardware(DisplayHardware *); |
| void setTransform(const Transform& tr); |
| status_t setOrientation(int orientation); |
| int getOrientation() const { return mOrientation; } |
| |
| const DisplayHardware& displayHardware() const; |
| const Transform& transform() const; |
| EGLDisplay getEGLDisplay() const; |
| |
| private: |
| GraphicPlane(const GraphicPlane&); |
| GraphicPlane operator = (const GraphicPlane&); |
| |
| DisplayHardware* mHw; |
| Transform mTransform; |
| Transform mOrientationTransform; |
| Transform mGlobalTransform; |
| int mOrientation; |
| }; |
| |
| // --------------------------------------------------------------------------- |
| |
| enum { |
| eTransactionNeeded = 0x01, |
| eTraversalNeeded = 0x02 |
| }; |
| |
| class SurfaceFlinger : public BnSurfaceComposer, protected Thread |
| { |
| public: |
| static void instantiate(); |
| static void shutdown(); |
| |
| SurfaceFlinger(); |
| virtual ~SurfaceFlinger(); |
| void init(); |
| |
| virtual status_t onTransact( |
| uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); |
| |
| virtual status_t dump(int fd, const Vector<String16>& args); |
| |
| // ISurfaceComposer interface |
| virtual sp<ISurfaceFlingerClient> createConnection(); |
| virtual sp<IMemoryHeap> getCblk() const; |
| virtual void bootFinished(); |
| virtual void openGlobalTransaction(); |
| virtual void closeGlobalTransaction(); |
| virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags); |
| virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags); |
| virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags); |
| virtual void signal() const; |
| |
| void screenReleased(DisplayID dpy); |
| void screenAcquired(DisplayID dpy); |
| |
| overlay_control_device_t* getOverlayEngine() const; |
| |
| |
| status_t removeLayer(const sp<LayerBase>& layer); |
| status_t addLayer(const sp<LayerBase>& layer); |
| status_t invalidateLayerVisibility(const sp<LayerBase>& layer); |
| |
| private: |
| friend class BClient; |
| friend class LayerBase; |
| friend class LayerBuffer; |
| friend class LayerBaseClient; |
| friend class LayerBaseClient::Surface; |
| friend class Layer; |
| friend class LayerBlur; |
| friend class LayerDim; |
| |
| sp<ISurface> createSurface(ClientID client, int pid, |
| ISurfaceFlingerClient::surface_data_t* params, |
| DisplayID display, uint32_t w, uint32_t h, PixelFormat format, |
| uint32_t flags); |
| |
| sp<LayerBaseClient> createNormalSurfaceLocked( |
| const sp<Client>& client, DisplayID display, |
| int32_t id, uint32_t w, uint32_t h, uint32_t flags, |
| PixelFormat& format); |
| |
| sp<LayerBaseClient> createBlurSurfaceLocked( |
| const sp<Client>& client, DisplayID display, |
| int32_t id, uint32_t w, uint32_t h, uint32_t flags); |
| |
| sp<LayerBaseClient> createDimSurfaceLocked( |
| const sp<Client>& client, DisplayID display, |
| int32_t id, uint32_t w, uint32_t h, uint32_t flags); |
| |
| sp<LayerBaseClient> createPushBuffersSurfaceLocked( |
| const sp<Client>& client, DisplayID display, |
| int32_t id, uint32_t w, uint32_t h, uint32_t flags); |
| |
| status_t removeSurface(SurfaceID surface_id); |
| status_t destroySurface(const sp<LayerBaseClient>& layer); |
| status_t setClientState(ClientID cid, int32_t count, const layer_state_t* states); |
| |
| |
| class LayerVector { |
| public: |
| inline LayerVector() { } |
| LayerVector(const LayerVector&); |
| inline size_t size() const { return layers.size(); } |
| inline sp<LayerBase> const* array() const { return layers.array(); } |
| ssize_t add(const sp<LayerBase>&, Vector< sp<LayerBase> >::compar_t); |
| ssize_t remove(const sp<LayerBase>&); |
| ssize_t reorder(const sp<LayerBase>&, Vector< sp<LayerBase> >::compar_t); |
| ssize_t indexOf(const sp<LayerBase>& key, size_t guess=0) const; |
| inline sp<LayerBase> operator [] (size_t i) const { return layers[i]; } |
| private: |
| KeyedVector< sp<LayerBase> , size_t> lookup; |
| Vector< sp<LayerBase> > layers; |
| }; |
| |
| struct State { |
| State() { |
| orientation = ISurfaceComposer::eOrientationDefault; |
| freezeDisplay = 0; |
| } |
| LayerVector layersSortedByZ; |
| uint8_t orientation; |
| uint8_t orientationType; |
| uint8_t freezeDisplay; |
| }; |
| |
| virtual bool threadLoop(); |
| virtual status_t readyToRun(); |
| virtual void onFirstRef(); |
| |
| public: // hack to work around gcc 4.0.3 bug |
| const GraphicPlane& graphicPlane(int dpy) const; |
| GraphicPlane& graphicPlane(int dpy); |
| private: |
| |
| void waitForEvent(); |
| public: // hack to work around gcc 4.0.3 bug |
| void signalEvent(); |
| private: |
| void signalDelayedEvent(nsecs_t delay); |
| |
| void handleConsoleEvents(); |
| void handleTransaction(uint32_t transactionFlags); |
| void handleTransactionLocked( |
| uint32_t transactionFlags, |
| Vector< sp<LayerBase> >& ditchedLayers); |
| |
| void computeVisibleRegions( |
| LayerVector& currentLayers, |
| Region& dirtyRegion, |
| Region& wormholeRegion); |
| |
| void handlePageFlip(); |
| bool lockPageFlip(const LayerVector& currentLayers); |
| void unlockPageFlip(const LayerVector& currentLayers); |
| void handleRepaint(); |
| void postFramebuffer(); |
| void composeSurfaces(const Region& dirty); |
| void unlockClients(); |
| |
| |
| void destroyConnection(ClientID cid); |
| sp<LayerBaseClient> getLayerUser_l(SurfaceID index) const; |
| status_t addLayer_l(const sp<LayerBase>& layer); |
| status_t removeLayer_l(const sp<LayerBase>& layer); |
| status_t purgatorizeLayer_l(const sp<LayerBase>& layer); |
| void free_resources_l(); |
| |
| uint32_t getTransactionFlags(uint32_t flags); |
| uint32_t setTransactionFlags(uint32_t flags, nsecs_t delay = 0); |
| void commitTransaction(); |
| |
| |
| friend class FreezeLock; |
| sp<FreezeLock> getFreezeLock() const; |
| inline void incFreezeCount() { |
| if (mFreezeCount == 0) |
| mFreezeDisplayTime = 0; |
| mFreezeCount++; |
| } |
| inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; } |
| inline bool hasFreezeRequest() const { return mFreezeDisplay; } |
| inline bool isFrozen() const { |
| return (mFreezeDisplay || mFreezeCount>0) && mBootFinished; |
| } |
| |
| |
| void debugFlashRegions(); |
| void debugShowFPS() const; |
| void drawWormhole() const; |
| |
| |
| mutable MessageQueue mEventQueue; |
| |
| |
| |
| // access must be protected by mStateLock |
| mutable Mutex mStateLock; |
| State mCurrentState; |
| State mDrawingState; |
| volatile int32_t mTransactionFlags; |
| volatile int32_t mTransactionCount; |
| Condition mTransactionCV; |
| bool mResizeTransationPending; |
| |
| // protected by mStateLock (but we could use another lock) |
| Tokenizer mTokens; |
| DefaultKeyedVector<ClientID, sp<Client> > mClientsMap; |
| DefaultKeyedVector<SurfaceID, sp<LayerBaseClient> > mLayerMap; |
| GraphicPlane mGraphicPlanes[1]; |
| bool mLayersRemoved; |
| Vector< sp<Client> > mDisconnectedClients; |
| |
| // constant members (no synchronization needed for access) |
| sp<IMemoryHeap> mServerHeap; |
| surface_flinger_cblk_t* mServerCblk; |
| GLuint mWormholeTexName; |
| nsecs_t mBootTime; |
| Permission mHardwareTest; |
| Permission mAccessSurfaceFlinger; |
| Permission mDump; |
| |
| // Can only accessed from the main thread, these members |
| // don't need synchronization |
| Region mDirtyRegion; |
| Region mDirtyRegionRemovedLayer; |
| Region mInvalidRegion; |
| Region mWormholeRegion; |
| bool mVisibleRegionsDirty; |
| bool mDeferReleaseConsole; |
| bool mFreezeDisplay; |
| int32_t mFreezeCount; |
| nsecs_t mFreezeDisplayTime; |
| |
| // don't use a lock for these, we don't care |
| int mDebugRegion; |
| int mDebugBackground; |
| volatile nsecs_t mDebugInSwapBuffers; |
| nsecs_t mLastSwapBufferTime; |
| volatile nsecs_t mDebugInTransaction; |
| nsecs_t mLastTransactionTime; |
| bool mBootFinished; |
| |
| // these are thread safe |
| mutable Barrier mReadyToRunBarrier; |
| |
| // atomic variables |
| enum { |
| eConsoleReleased = 1, |
| eConsoleAcquired = 2 |
| }; |
| volatile int32_t mConsoleSignals; |
| |
| // only written in the main thread, only read in other threads |
| volatile int32_t mSecureFrameBuffer; |
| }; |
| |
| // --------------------------------------------------------------------------- |
| |
| class FreezeLock : public LightRefBase<FreezeLock> { |
| SurfaceFlinger* mFlinger; |
| public: |
| FreezeLock(SurfaceFlinger* flinger) |
| : mFlinger(flinger) { |
| mFlinger->incFreezeCount(); |
| } |
| ~FreezeLock() { |
| mFlinger->decFreezeCount(); |
| } |
| }; |
| |
| // --------------------------------------------------------------------------- |
| |
| class BClient : public BnSurfaceFlingerClient |
| { |
| public: |
| BClient(SurfaceFlinger *flinger, ClientID cid, |
| const sp<IMemoryHeap>& cblk); |
| ~BClient(); |
| |
| // ISurfaceFlingerClient interface |
| virtual sp<IMemoryHeap> getControlBlock() const; |
| |
| virtual sp<ISurface> createSurface( |
| surface_data_t* params, int pid, |
| DisplayID display, uint32_t w, uint32_t h,PixelFormat format, |
| uint32_t flags); |
| |
| virtual status_t destroySurface(SurfaceID surfaceId); |
| virtual status_t setState(int32_t count, const layer_state_t* states); |
| |
| private: |
| ClientID mId; |
| SurfaceFlinger* mFlinger; |
| sp<IMemoryHeap> mCblk; |
| }; |
| |
| // --------------------------------------------------------------------------- |
| }; // namespace android |
| |
| #endif // ANDROID_SURFACE_FLINGER_H |