| /* | 
 |  * 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_LAYER_H | 
 | #define ANDROID_LAYER_H | 
 |  | 
 | #include <stdint.h> | 
 | #include <sys/types.h> | 
 |  | 
 | #include <ui/GraphicBuffer.h> | 
 | #include <ui/PixelFormat.h> | 
 | #include <pixelflinger/pixelflinger.h> | 
 |  | 
 | #include <EGL/egl.h> | 
 | #include <EGL/eglext.h> | 
 | #include <GLES/gl.h> | 
 | #include <GLES/glext.h> | 
 |  | 
 | #include "LayerBase.h" | 
 | #include "Transform.h" | 
 | #include "TextureManager.h" | 
 |  | 
 | namespace android { | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 |  | 
 | class FreezeLock; | 
 | class Client; | 
 | class GLExtensions; | 
 | class UserClient; | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 |  | 
 | class Layer : public LayerBaseClient | 
 | { | 
 | public: | 
 |             Layer(SurfaceFlinger* flinger, DisplayID display, | 
 |                     const sp<Client>& client); | 
 |  | 
 |     virtual ~Layer(); | 
 |  | 
 |     virtual const char* getTypeId() const { return "Layer"; } | 
 |  | 
 |     // the this layer's size and format | 
 |     status_t setBuffers(uint32_t w, uint32_t h,  | 
 |             PixelFormat format, uint32_t flags=0); | 
 |  | 
 |     // associate a UserClient to this Layer | 
 |     status_t setToken(const sp<UserClient>& uc, SharedClient* sc, int32_t idx); | 
 |     int32_t getToken() const; | 
 |     sp<UserClient> getClient() const; | 
 |  | 
 |     // Set this Layer's buffers size | 
 |     void setBufferSize(uint32_t w, uint32_t h); | 
 |     bool isFixedSize() const; | 
 |  | 
 |     // LayerBase interface | 
 |     virtual void onDraw(const Region& clip) const; | 
 |     virtual uint32_t doTransaction(uint32_t transactionFlags); | 
 |     virtual void lockPageFlip(bool& recomputeVisibleRegions); | 
 |     virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion); | 
 |     virtual void finishPageFlip(); | 
 |     virtual bool needsBlending() const      { return mNeedsBlending; } | 
 |     virtual bool needsDithering() const     { return mNeedsDithering; } | 
 |     virtual bool needsFiltering() const; | 
 |     virtual bool isSecure() const           { return mSecure; } | 
 |     virtual sp<Surface> createSurface() const; | 
 |     virtual status_t ditch(); | 
 |     virtual void onRemoved(); | 
 |  | 
 |     // only for debugging | 
 |     inline sp<GraphicBuffer> getBuffer(int i) const { | 
 |         return mBufferManager.getBuffer(i); } | 
 |     // only for debugging | 
 |     inline const sp<FreezeLock>&  getFreezeLock() const { | 
 |         return mFreezeLock; } | 
 |  | 
 | protected: | 
 |     virtual void dump(String8& result, char* scratch, size_t size) const; | 
 |  | 
 | private: | 
 |     void reloadTexture(const Region& dirty); | 
 |     uint32_t getEffectiveUsage(uint32_t usage) const; | 
 |     sp<GraphicBuffer> requestBuffer(int bufferIdx, | 
 |             uint32_t w, uint32_t h, uint32_t format, uint32_t usage); | 
 |     status_t setBufferCount(int bufferCount); | 
 |  | 
 |     // ----------------------------------------------------------------------- | 
 |  | 
 |     class SurfaceLayer : public LayerBaseClient::Surface { | 
 |     public: | 
 |         SurfaceLayer(const sp<SurfaceFlinger>& flinger, const sp<Layer>& owner); | 
 |         ~SurfaceLayer(); | 
 |     private: | 
 |         virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, | 
 |                 uint32_t w, uint32_t h, uint32_t format, uint32_t usage); | 
 |         virtual status_t setBufferCount(int bufferCount); | 
 |         sp<Layer> getOwner() const { | 
 |             return static_cast<Layer*>(Surface::getOwner().get()); | 
 |         } | 
 |     }; | 
 |     friend class SurfaceLayer; | 
 |  | 
 |     // ----------------------------------------------------------------------- | 
 |  | 
 |     class ClientRef { | 
 |         ClientRef(const ClientRef& rhs); | 
 |         ClientRef& operator = (const ClientRef& rhs); | 
 |         mutable Mutex mLock; | 
 |         // binder thread, page-flip thread | 
 |         sp<SharedBufferServer> mControlBlock; | 
 |         wp<UserClient> mUserClient; | 
 |         int32_t mToken; | 
 |     public: | 
 |         ClientRef(); | 
 |         ~ClientRef(); | 
 |         int32_t getToken() const; | 
 |         sp<UserClient> getClient() const; | 
 |         status_t setToken(const sp<UserClient>& uc, | 
 |                 const sp<SharedBufferServer>& sharedClient, int32_t token); | 
 |         sp<UserClient> getUserClientUnsafe() const; | 
 |         class Access { | 
 |             Access(const Access& rhs); | 
 |             Access& operator = (const Access& rhs); | 
 |             sp<UserClient> mUserClientStrongRef; | 
 |             sp<SharedBufferServer> mControlBlock; | 
 |         public: | 
 |             Access(const ClientRef& ref); | 
 |             ~Access(); | 
 |             inline SharedBufferServer* get() const { return mControlBlock.get(); } | 
 |         }; | 
 |         friend class Access; | 
 |     }; | 
 |  | 
 |     // ----------------------------------------------------------------------- | 
 |  | 
 |     class BufferManager { | 
 |         static const size_t NUM_BUFFERS = 2; | 
 |         struct BufferData { | 
 |             sp<GraphicBuffer>   buffer; | 
 |             Image               texture; | 
 |         }; | 
 |         // this lock protect mBufferData[].buffer but since there | 
 |         // is very little contention, we have only one like for | 
 |         // the whole array, we also use it to protect mNumBuffers. | 
 |         mutable Mutex mLock; | 
 |         BufferData          mBufferData[SharedBufferStack::NUM_BUFFER_MAX]; | 
 |         size_t              mNumBuffers; | 
 |         Texture             mFailoverTexture; | 
 |         TextureManager&     mTextureManager; | 
 |         ssize_t             mActiveBuffer; | 
 |         bool                mFailover; | 
 |         static status_t destroyTexture(Image* tex, EGLDisplay dpy); | 
 |  | 
 |     public: | 
 |         static size_t getDefaultBufferCount() { return NUM_BUFFERS; } | 
 |         BufferManager(TextureManager& tm); | 
 |         ~BufferManager(); | 
 |  | 
 |         // detach/attach buffer from/to given index | 
 |         sp<GraphicBuffer> detachBuffer(size_t index); | 
 |         status_t attachBuffer(size_t index, const sp<GraphicBuffer>& buffer); | 
 |         // resize the number of active buffers | 
 |         status_t resize(size_t size); | 
 |  | 
 |         // ---------------------------------------------- | 
 |         // must be called from GL thread | 
 |  | 
 |         // set/get active buffer index | 
 |         status_t setActiveBufferIndex(size_t index); | 
 |         size_t getActiveBufferIndex() const; | 
 |         // return the active buffer | 
 |         sp<GraphicBuffer> getActiveBuffer() const; | 
 |         // return the active texture (or fail-over) | 
 |         Texture getActiveTexture() const; | 
 |         // frees resources associated with all buffers | 
 |         status_t destroy(EGLDisplay dpy); | 
 |         // load bitmap data into the active buffer | 
 |         status_t loadTexture(const Region& dirty, const GGLSurface& t); | 
 |         // make active buffer an EGLImage if needed | 
 |         status_t initEglImage(EGLDisplay dpy, | 
 |                 const sp<GraphicBuffer>& buffer); | 
 |  | 
 |         // ---------------------------------------------- | 
 |         // only for debugging | 
 |         sp<GraphicBuffer> getBuffer(size_t index) const; | 
 |     }; | 
 |  | 
 |     // ----------------------------------------------------------------------- | 
 |  | 
 |     // thread-safe | 
 |     ClientRef mUserClientRef; | 
 |  | 
 |     // constants | 
 |     sp<Surface> mSurface; | 
 |     PixelFormat mFormat; | 
 |     const GLExtensions& mGLExtensions; | 
 |     bool mNeedsBlending; | 
 |     bool mNeedsDithering; | 
 |  | 
 |     // page-flip thread (currently main thread) | 
 |     bool mSecure; | 
 |     Region mPostedDirtyRegion; | 
 |  | 
 |     // page-flip thread and transaction thread (currently main thread) | 
 |     sp<FreezeLock>  mFreezeLock; | 
 |  | 
 |     // see threading usage in declaration | 
 |     TextureManager mTextureManager; | 
 |     BufferManager mBufferManager; | 
 |  | 
 |     // binder thread, transaction thread | 
 |     mutable Mutex mLock; | 
 |     uint32_t mWidth; | 
 |     uint32_t mHeight; | 
 |     uint32_t mReqWidth; | 
 |     uint32_t mReqHeight; | 
 |     uint32_t mReqFormat; | 
 |     bool mFixedSize; | 
 | }; | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 |  | 
 | }; // namespace android | 
 |  | 
 | #endif // ANDROID_LAYER_H |