/* // 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); virtual uint32_t getFpsDivider(); #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; uint32_t mFpsDivider; }; } } #endif /* VIRTUAL_DEVICE_H */