| /* |
| * 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 |