/*
// Copyright (c) 2014 Intel Corporation 
//
// 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 VIRTUAL_DEVICE_H
#define VIRTUAL_DEVICE_H

#include <IDisplayDevice.h>
#include <SimpleThread.h>
#include <IVideoPayloadManager.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <utils/Vector.h>
#include <utils/List.h>
#ifdef INTEL_WIDI
#include "IFrameServer.h"
#endif
#include <va/va.h>
#include <va/va_vpp.h>

namespace android {
namespace intel {

class Hwcomposer;
class DisplayPlaneManager;
class IVideoPayloadManager;
class SoftVsyncObserver;

#ifdef INTEL_WIDI
class VirtualDevice : public IDisplayDevice, public BnFrameServer {
#else
class VirtualDevice : public IDisplayDevice, public RefBase{
#endif
protected:
    class VAMappedHandle;
    class VAMappedHandleObject;
    struct CachedBuffer : public android::RefBase {
        CachedBuffer(BufferManager *mgr, buffer_handle_t handle);
        ~CachedBuffer();
        BufferManager *manager;
        BufferMapper *mapper;
        VAMappedHandle *vaMappedHandle;
        buffer_handle_t cachedKhandle;
    };
    struct HeldDecoderBuffer : public android::RefBase {
        HeldDecoderBuffer(const sp<VirtualDevice>& vd, const android::sp<CachedBuffer>& cachedBuffer);
        virtual ~HeldDecoderBuffer();
        android::sp<VirtualDevice> vd;
        android::sp<CachedBuffer> cachedBuffer;
    };
#ifdef INTEL_WIDI
    struct Configuration {
        sp<IFrameTypeChangeListener> typeChangeListener;
        sp<IFrameListener> frameListener;
        FrameProcessingPolicy policy;
        bool frameServerActive;
        bool extendedModeEnabled;
        bool forceNotifyFrameType;
        bool forceNotifyBufferInfo;
    };
#endif
    class BufferList {
    public:
        BufferList(VirtualDevice& vd, const char* name, uint32_t limit, uint32_t format, uint32_t usage);
        buffer_handle_t get(uint32_t width, uint32_t height, sp<RefBase>* heldBuffer);
        void clear();
    private:
        struct HeldBuffer;
        VirtualDevice& mVd;
        const char* mName;
        android::List<buffer_handle_t> mAvailableBuffers;
        const uint32_t mLimit;
        const uint32_t mFormat;
        const uint32_t mUsage;
        uint32_t mBuffersToCreate;
        uint32_t mWidth;
        uint32_t mHeight;
    };
    struct Task;
    struct RenderTask;
    struct ComposeTask;
    struct EnableVspTask;
    struct DisableVspTask;
    struct BlitTask;
    struct FrameTypeChangedTask;
    struct BufferInfoChangedTask;
    struct OnFrameReadyTask;

    Mutex mConfigLock;
#ifdef INTEL_WIDI
    Configuration mCurrentConfig;
    Configuration mNextConfig;
#endif
    ssize_t mRgbLayer;
    ssize_t mYuvLayer;
    bool mProtectedMode;

    buffer_handle_t mExtLastKhandle;
    int64_t mExtLastTimestamp;

    int64_t mRenderTimestamp;

    Mutex mTaskLock; // for task queue and buffer lists
    BufferList mCscBuffers;
    BufferList mRgbUpscaleBuffers;
    DECLARE_THREAD(WidiBlitThread, VirtualDevice);
    Condition mRequestQueued;
    Condition mRequestDequeued;
    Vector< sp<Task> > mTasks;

    // fence info
    int mSyncTimelineFd;
    unsigned mNextSyncPoint;
    bool mExpectAcquireFences;
#ifdef INTEL_WIDI
    FrameInfo mLastInputFrameInfo;
    FrameInfo mLastOutputFrameInfo;
#endif
    int32_t mVideoFramerate;

    android::KeyedVector<buffer_handle_t, android::sp<CachedBuffer> > mMappedBufferCache;
    android::Mutex mHeldBuffersLock;
    android::KeyedVector<buffer_handle_t, android::sp<android::RefBase> > mHeldBuffers;

    // VSP
    bool mVspInUse;
    bool mVspEnabled;
    uint32_t mVspWidth;
    uint32_t mVspHeight;
    VADisplay va_dpy;
    VAConfigID va_config;
    VAContextID va_context;
    VASurfaceID va_blank_yuv_in;
    VASurfaceID va_blank_rgb_in;
    android::KeyedVector<buffer_handle_t, android::sp<VAMappedHandleObject> > mVaMapCache;

    bool mVspUpscale;
    bool mDebugVspClear;
    bool mDebugVspDump;
    uint32_t mDebugCounter;

private:
    android::sp<CachedBuffer> getMappedBuffer(buffer_handle_t handle);

    bool sendToWidi(hwc_display_contents_1_t *display);
    bool queueCompose(hwc_display_contents_1_t *display);
    bool queueColorConvert(hwc_display_contents_1_t *display);
#ifdef INTEL_WIDI
    bool handleExtendedMode(hwc_display_contents_1_t *display);

    void queueFrameTypeInfo(const FrameInfo& inputFrameInfo);
    void queueBufferInfo(const FrameInfo& outputFrameInfo);
#endif
    void colorSwap(buffer_handle_t src, buffer_handle_t dest, uint32_t pixelCount);
    void vspPrepare(uint32_t width, uint32_t height);
    void vspEnable(uint32_t width, uint32_t height);
    void vspDisable();
    void vspCompose(VASurfaceID videoIn, VASurfaceID rgbIn, VASurfaceID videoOut,
                    const VARectangle* surface_region, const VARectangle* output_region);

    bool getFrameOfSize(uint32_t width, uint32_t height, const IVideoPayloadManager::MetaData& metadata, IVideoPayloadManager::Buffer& info);
    void setMaxDecodeResolution(uint32_t width, uint32_t height);

public:
    VirtualDevice(Hwcomposer& hwc);
    virtual ~VirtualDevice();
    bool isFrameServerActive() const;

public:
    virtual bool prePrepare(hwc_display_contents_1_t *display);
    virtual bool prepare(hwc_display_contents_1_t *display);
    virtual bool commit(hwc_display_contents_1_t *display,
                          IDisplayContext *context);

    virtual bool vsyncControl(bool enabled);
    virtual bool blank(bool blank);
    virtual bool getDisplaySize(int *width, int *height);
    virtual bool getDisplayConfigs(uint32_t *configs,
                                       size_t *numConfigs);
    virtual bool getDisplayAttributes(uint32_t config,
                                          const uint32_t *attributes,
                                          int32_t *values);
    virtual bool compositionComplete();
    virtual bool initialize();
    virtual void deinitialize();
    virtual bool isConnected() const;
    virtual const char* getName() const;
    virtual int getType() const;
    virtual void onVsync(int64_t timestamp);
    virtual void dump(Dump& d);
#ifdef INTEL_WIDI
    // IFrameServer methods
    virtual android::status_t start(sp<IFrameTypeChangeListener> frameTypeChangeListener);
    virtual android::status_t stop(bool isConnected);
	/* TODO: 64-bit - this handle of size 32-bit is a problem for 64-bit */
    virtual android::status_t notifyBufferReturned(int handle);
    virtual android::status_t setResolution(const FrameProcessingPolicy& policy, android::sp<IFrameListener> listener);
#endif
    virtual bool setPowerMode(int mode);
    virtual int  getActiveConfig();
    virtual bool setActiveConfig(int index);

protected:
    bool mInitialized;
    Hwcomposer& mHwc;
    IVideoPayloadManager *mPayloadManager;
    SoftVsyncObserver *mVsyncObserver;
    uint32_t mOrigContentWidth;
    uint32_t mOrigContentHeight;
    bool mFirstVideoFrame;
    bool mLastConnectionStatus;
    uint32_t mCachedBufferCapcity;
    uint32_t mDecWidth;
    uint32_t mDecHeight;
    bool mIsForceCloneMode;
};

}
}

#endif /* VIRTUAL_DEVICE_H */
