/*
 * 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_BUFFER_H
#define ANDROID_LAYER_BUFFER_H

#include <stdint.h>
#include <sys/types.h>

#include "LayerBase.h"

struct copybit_device_t;

namespace android {

// ---------------------------------------------------------------------------

class Buffer;
class Region;
class OverlayRef;

// ---------------------------------------------------------------------------

class LayerBuffer : public LayerBaseClient
{
    class Source : public LightRefBase<Source> {
    public:
        Source(LayerBuffer& layer);
        virtual ~Source();
        virtual void onDraw(const Region& clip) const;
        virtual void onTransaction(uint32_t flags);
        virtual void onVisibilityResolved(const Transform& planeTransform);
        virtual void postBuffer(ssize_t offset);
        virtual void unregisterBuffers();
        virtual bool transformed() const;
        virtual void destroy() { }
    protected:
        LayerBuffer& mLayer;
    };

public:
    static const uint32_t typeInfo;
    static const char* const typeID;
    virtual char const* getTypeID() const { return typeID; }
    virtual uint32_t getTypeInfo() const { return typeInfo; }

            LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
                    const sp<Client>& client, int32_t i);
        virtual ~LayerBuffer();

    virtual void onFirstRef();
    virtual bool needsBlending() const;

    virtual sp<LayerBaseClient::Surface> createSurface() const;
    virtual status_t ditch();
    virtual void onDraw(const Region& clip) const;
    virtual uint32_t doTransaction(uint32_t flags);
    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
    virtual bool transformed() const;

    status_t registerBuffers(const ISurface::BufferHeap& buffers);
    void postBuffer(ssize_t offset);
    void unregisterBuffers();
    sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format,
            int32_t orientation);
    
    sp<Source> getSource() const;
    sp<Source> clearSource();
    void setNeedsBlending(bool blending);
    Rect getTransformedBounds() const {
        return mTransformedBounds;
    }

    void serverDestroy();

private:
    struct NativeBuffer {
        copybit_image_t   img;
        copybit_rect_t    crop;
    };

    static gralloc_module_t const* sGrallocModule;
    static gralloc_module_t const* getGrallocModule() {
        return sGrallocModule;
    }

    class Buffer : public LightRefBase<Buffer> {
    public:
        Buffer(const ISurface::BufferHeap& buffers,
                ssize_t offset, size_t bufferSize);
        inline bool supportsCopybit() const {
            return mSupportsCopybit;
        }
        inline status_t getStatus() const {
            return mBufferHeap.heap!=0 ? NO_ERROR : NO_INIT;
        }
        inline const NativeBuffer& getBuffer() const {
            return mNativeBuffer;
        }
    protected:
        friend class LightRefBase<Buffer>;
        Buffer& operator = (const Buffer& rhs);
        Buffer(const Buffer& rhs);
        ~Buffer();
    private:
        ISurface::BufferHeap    mBufferHeap;
        NativeBuffer            mNativeBuffer;
        bool                    mSupportsCopybit;
    };

    class BufferSource : public Source {
    public:
        BufferSource(LayerBuffer& layer, const ISurface::BufferHeap& buffers);
        virtual ~BufferSource();

        status_t getStatus() const { return mStatus; }
        sp<Buffer> getBuffer() const;
        void setBuffer(const sp<Buffer>& buffer);

        virtual void onDraw(const Region& clip) const;
        virtual void postBuffer(ssize_t offset);
        virtual void unregisterBuffers();
        virtual bool transformed() const;
        virtual void destroy() { }
    private:
        status_t initTempBuffer() const;
        void clearTempBufferImage() const;
        mutable Mutex                   mBufferSourceLock;
        sp<Buffer>                      mBuffer;
        status_t                        mStatus;
        ISurface::BufferHeap            mBufferHeap;
        size_t                          mBufferSize;
        mutable LayerBase::Texture      mTexture;
        mutable NativeBuffer            mTempBuffer;
        mutable bool                    mUseEGLImageDirectly;
    };
    
    class OverlaySource : public Source {
    public:
        OverlaySource(LayerBuffer& layer,
                sp<OverlayRef>* overlayRef, 
                uint32_t w, uint32_t h, int32_t format, int32_t orientation);
        virtual ~OverlaySource();
        virtual void onDraw(const Region& clip) const;
        virtual void onTransaction(uint32_t flags);
        virtual void onVisibilityResolved(const Transform& planeTransform);
        virtual void destroy();
    private:

        class OverlayChannel : public BnOverlay {
            wp<LayerBuffer> mLayer;
            virtual void destroy() {
                sp<LayerBuffer> layer(mLayer.promote());
                if (layer != 0) {
                    layer->serverDestroy();
                }
            }
        public:
            OverlayChannel(const sp<LayerBuffer>& layer)
                : mLayer(layer) {
            }
        };
        
        friend class OverlayChannel;
        bool mVisibilityChanged;

        overlay_t* mOverlay;        
        overlay_handle_t mOverlayHandle;
        overlay_control_device_t* mOverlayDevice;
        uint32_t mWidth;
        uint32_t mHeight;
        int32_t mFormat;
        int32_t mWidthStride;
        int32_t mHeightStride;
        int32_t mOrientation;
        mutable Mutex mOverlaySourceLock;
        bool mInitialized;
    };


    class SurfaceLayerBuffer : public LayerBaseClient::Surface
    {
    public:
        SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger,
                        SurfaceID id, const sp<LayerBuffer>& owner);
        virtual ~SurfaceLayerBuffer();

        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
        virtual void postBuffer(ssize_t offset);
        virtual void unregisterBuffers();
        
        virtual sp<OverlayRef> createOverlay(
                uint32_t w, uint32_t h, int32_t format, int32_t orientation);
    private:
        sp<LayerBuffer> getOwner() const {
            return static_cast<LayerBuffer*>(Surface::getOwner().get());
        }
    };

    mutable Mutex   mLock;
    sp<Source>      mSource;
    sp<Surface>     mSurface;
    bool            mInvalidate;
    bool            mNeedsBlending;
    copybit_device_t* mBlitEngine;
};

// ---------------------------------------------------------------------------

}; // namespace android

#endif // ANDROID_LAYER_BUFFER_H
