/*
 * 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);
    
    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);
        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;
    };

    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;
        mutable Mutex                   mBufferSourceLock;
        sp<Buffer>                      mBuffer;
        status_t                        mStatus;
        ISurface::BufferHeap            mBufferHeap;
        size_t                          mBufferSize;
        mutable LayerBase::Texture      mTexture;
        mutable NativeBuffer            mTempBuffer;
        mutable sp<GraphicBuffer>       mTempGraphicBuffer;
    };
    
    class OverlaySource : public Source {
    public:
        OverlaySource(LayerBuffer& layer,
                sp<OverlayRef>* overlayRef, 
                uint32_t w, uint32_t h, int32_t format);
        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;
        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);
    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
