364 lines
12 KiB
C++
364 lines
12 KiB
C++
/*
|
|
* Copyright (C) 2012 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 _EXYNOSDEVICE_H
|
|
#define _EXYNOSDEVICE_H
|
|
|
|
#include <aidl/com/google/hardware/pixel/display/BnDisplay.h>
|
|
#include <cutils/atomic.h>
|
|
#include <displaycolor/displaycolor.h>
|
|
#include <hardware/hwcomposer2.h>
|
|
#include <hardware_legacy/uevent.h>
|
|
#include <sys/resource.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <utils/Condition.h>
|
|
#include <utils/Mutex.h>
|
|
#include <utils/Trace.h>
|
|
#include <utils/Vector.h>
|
|
|
|
#include <atomic>
|
|
#include <map>
|
|
#include <thread>
|
|
|
|
#include "ExynosHWC.h"
|
|
#include "ExynosHWCHelper.h"
|
|
#include "ExynosHWCModule.h"
|
|
|
|
#define MAX_DEV_NAME 128
|
|
#define ERROR_LOG_PATH0 "/data/vendor/log/hwc"
|
|
#define ERROR_LOG_PATH1 "/data/log"
|
|
#define ERR_LOG_SIZE (1024*1024) // 1MB
|
|
#define FENCE_ERR_LOG_SIZE (1024*1024) // 1MB
|
|
|
|
#ifndef DOZE_VSYNC_PERIOD
|
|
#define DOZE_VSYNC_PERIOD 33333333 // 30fps
|
|
#endif
|
|
|
|
#ifndef DRM_DEVICE_PATH
|
|
#define DRM_DEVICE_PATH "/dev/dri/card0"
|
|
#endif
|
|
|
|
#ifndef WRITEBACK_CAPTURE_PATH
|
|
#define WRITEBACK_CAPTURE_PATH "/data/vendor/log/hwc"
|
|
#endif
|
|
|
|
using HbmState = ::aidl::com::google::hardware::pixel::display::HbmState;
|
|
using LbeState = ::aidl::com::google::hardware::pixel::display::LbeState;
|
|
using PanelCalibrationStatus = ::aidl::com::google::hardware::pixel::display::PanelCalibrationStatus;
|
|
|
|
using namespace android;
|
|
|
|
struct exynos_callback_info_t {
|
|
hwc2_callback_data_t callbackData;
|
|
hwc2_function_pointer_t funcPointer;
|
|
};
|
|
|
|
typedef struct exynos_hwc_control {
|
|
uint32_t forceGpu;
|
|
uint32_t windowUpdate;
|
|
uint32_t forcePanic;
|
|
uint32_t skipStaticLayers;
|
|
uint32_t skipM2mProcessing;
|
|
uint32_t skipResourceAssign;
|
|
uint32_t multiResolution;
|
|
uint32_t dumpMidBuf;
|
|
uint32_t displayMode;
|
|
uint32_t setDDIScaler;
|
|
uint32_t useDynamicRecomp;
|
|
uint32_t skipWinConfig;
|
|
uint32_t skipValidate;
|
|
uint32_t doFenceFileDump;
|
|
uint32_t fenceTracer;
|
|
uint32_t sysFenceLogging;
|
|
} exynos_hwc_control_t;
|
|
|
|
typedef struct update_time_info {
|
|
struct timeval lastUeventTime;
|
|
struct timeval lastEnableVsyncTime;
|
|
struct timeval lastDisableVsyncTime;
|
|
struct timeval lastValidateTime;
|
|
struct timeval lastPresentTime;
|
|
} update_time_info_t;
|
|
|
|
enum {
|
|
GEOMETRY_LAYER_TYPE_CHANGED = 1ULL << 0,
|
|
GEOMETRY_LAYER_DATASPACE_CHANGED = 1ULL << 1,
|
|
GEOMETRY_LAYER_DISPLAYFRAME_CHANGED = 1ULL << 2,
|
|
GEOMETRY_LAYER_SOURCECROP_CHANGED = 1ULL << 3,
|
|
GEOMETRY_LAYER_TRANSFORM_CHANGED = 1ULL << 4,
|
|
GEOMETRY_LAYER_ZORDER_CHANGED = 1ULL << 5,
|
|
GEOMETRY_LAYER_FPS_CHANGED = 1ULL << 6,
|
|
GEOMETRY_LAYER_FLAG_CHANGED = 1ULL << 7,
|
|
GEOMETRY_LAYER_PRIORITY_CHANGED = 1ULL << 8,
|
|
GEOMETRY_LAYER_COMPRESSED_CHANGED = 1ULL << 9,
|
|
GEOMETRY_LAYER_BLEND_CHANGED = 1ULL << 10,
|
|
GEOMETRY_LAYER_FORMAT_CHANGED = 1ULL << 11,
|
|
GEOMETRY_LAYER_DRM_CHANGED = 1ULL << 12,
|
|
GEOMETRY_LAYER_IGNORE_CHANGED = 1ULL << 13,
|
|
GEOMETRY_LAYER_WHITEPOINT_CHANGED = 1ULL << 14,
|
|
GEOMETRY_LAYER_FRONT_BUFFER_USAGE_CHANGED = 1ULL << 15,
|
|
GEOMETRY_LAYER_UNKNOWN_CHANGED = 1ULL << 16,
|
|
/* 1ULL << 17 */
|
|
/* 1ULL << 18 */
|
|
/* 1ULL << 19 */
|
|
GEOMETRY_DISPLAY_LAYER_ADDED = 1ULL << 20,
|
|
GEOMETRY_DISPLAY_LAYER_REMOVED = 1ULL << 21,
|
|
GEOMETRY_DISPLAY_CONFIG_CHANGED = 1ULL << 22,
|
|
GEOMETRY_DISPLAY_RESOLUTION_CHANGED = 1ULL << 23,
|
|
GEOMETRY_DISPLAY_SINGLEBUF_CHANGED = 1ULL << 24,
|
|
GEOMETRY_DISPLAY_FORCE_VALIDATE = 1ULL << 25,
|
|
GEOMETRY_DISPLAY_COLOR_MODE_CHANGED = 1ULL << 26,
|
|
GEOMETRY_DISPLAY_DYNAMIC_RECOMPOSITION = 1ULL << 27,
|
|
GEOMETRY_DISPLAY_POWER_ON = 1ULL << 28,
|
|
GEOMETRY_DISPLAY_POWER_OFF = 1ULL << 29,
|
|
GEOMETRY_DISPLAY_COLOR_TRANSFORM_CHANGED = 1ULL << 30,
|
|
GEOMETRY_DISPLAY_DATASPACE_CHANGED = 1ULL << 31,
|
|
/* 1ULL << 32 */
|
|
/* 1ULL << 33 */
|
|
/* 1ULL << 34 */
|
|
/* 1ULL << 35 */
|
|
GEOMETRY_DEVICE_DISPLAY_ADDED = 1ULL << 36,
|
|
GEOMETRY_DEVICE_DISPLAY_REMOVED = 1ULL << 37,
|
|
GEOMETRY_DEVICE_CONFIG_CHANGED = 1ULL << 38,
|
|
GEOMETRY_DEVICE_DISP_MODE_CHAGED = 1ULL << 39,
|
|
GEOMETRY_DEVICE_SCENARIO_CHANGED = 1ULL << 40,
|
|
|
|
GEOMETRY_ERROR_CASE = 1ULL << 63,
|
|
};
|
|
|
|
class ExynosDevice;
|
|
class ExynosDisplay;
|
|
class ExynosResourceManager;
|
|
class ExynosDeviceInterface;
|
|
|
|
class ExynosDevice {
|
|
public:
|
|
/**
|
|
* TODO : Should be defined as ExynosDisplay type
|
|
* Display list that managed by Device.
|
|
*/
|
|
android::Vector< ExynosDisplay* > mDisplays;
|
|
|
|
int mNumVirtualDisplay;
|
|
|
|
/**
|
|
* Resource manager object that is used to manage HW resources and assign resources to each layers
|
|
*/
|
|
ExynosResourceManager *mResourceManager;
|
|
|
|
/**
|
|
* Geometry change will be saved by bit map.
|
|
* ex) Display create/destory.
|
|
*/
|
|
uint64_t mGeometryChanged;
|
|
|
|
/**
|
|
* If Panel has not self-refresh feature, dynamic recomposition will be enabled.
|
|
*/
|
|
std::thread mDRThread;
|
|
volatile int32_t mDRThreadStatus;
|
|
std::atomic<bool> mDRLoopStatus;
|
|
bool mPrimaryBlank;
|
|
std::mutex mDRWakeUpMutex;
|
|
std::condition_variable mDRWakeUpCondition;
|
|
|
|
/**
|
|
* Callback informations those are used by SurfaceFlinger.
|
|
* - VsyncCallback: Vsync detect callback.
|
|
* - RefreshCallback: Callback by refresh request from HWC.
|
|
* - HotplugCallback: Hot plug event by new display hardware.
|
|
*/
|
|
|
|
/** TODO : Array size shuld be checked */
|
|
exynos_callback_info_t mCallbackInfos[HWC2_CALLBACK_SEAMLESS_POSSIBLE + 1];
|
|
|
|
std::map<uint32_t, exynos_callback_info_t> mHwc3CallbackInfos;
|
|
Mutex mDeviceCallbackMutex;
|
|
|
|
/**
|
|
* Thread variables
|
|
*/
|
|
int mVsyncFd;
|
|
int mExtVsyncFd;
|
|
|
|
/**
|
|
* mDisplayId of display that has the slowest fps.
|
|
* HWC uses vsync of display that has the slowest fps to main vsync.
|
|
*/
|
|
uint32_t mVsyncDisplayId;
|
|
uint64_t mTimestamp;
|
|
|
|
uint32_t mDisplayMode;
|
|
|
|
// Variable for fence tracer
|
|
std::map<int, HwcFenceInfo> mFenceInfos GUARDED_BY(mFenceMutex);
|
|
std::mutex mFenceMutex;
|
|
|
|
/**
|
|
* This will be initialized with differnt class
|
|
* that inherits ExynosDeviceInterface according to
|
|
* interface type.
|
|
*/
|
|
std::unique_ptr<ExynosDeviceInterface> mDeviceInterface;
|
|
|
|
// Con/Destructors
|
|
ExynosDevice();
|
|
virtual ~ExynosDevice();
|
|
|
|
bool isFirstValidate();
|
|
bool isLastValidate(ExynosDisplay *display);
|
|
|
|
/**
|
|
* @param outSize
|
|
* @param * outBuffer
|
|
*/
|
|
|
|
void dynamicRecompositionThreadCreate();
|
|
static void* dynamicRecompositionThreadLoop(void *data);
|
|
|
|
|
|
/**
|
|
* @param display
|
|
*/
|
|
ExynosDisplay* getDisplay(uint32_t display);
|
|
|
|
/**
|
|
* Device Functions for HWC 2.0
|
|
*/
|
|
|
|
/**
|
|
* Descriptor: HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY
|
|
* HWC2_PFN_CREATE_VIRTUAL_DISPLAY
|
|
*/
|
|
int32_t createVirtualDisplay(
|
|
uint32_t width, uint32_t height, int32_t *format, ExynosDisplay *display);
|
|
|
|
/**
|
|
* Descriptor: HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY
|
|
* HWC2_PFN_DESTROY_VIRTUAL_DISPLAY
|
|
*/
|
|
int32_t destroyVirtualDisplay(
|
|
ExynosDisplay *display);
|
|
|
|
/**
|
|
* Descriptor: HWC2_FUNCTION_DUMP
|
|
* HWC2_PFN_DUMP
|
|
*/
|
|
void dump(uint32_t *outSize, char *outBuffer);
|
|
|
|
/**
|
|
* Descriptor: HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT
|
|
* HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT
|
|
*/
|
|
/* TODO overide check!! */
|
|
uint32_t getMaxVirtualDisplayCount();
|
|
|
|
/* Descriptor: HWC2_FUNCTION_GET_LAYER_GENERIC_METADATA_KEY
|
|
*/
|
|
void getLayerGenericMetadataKey(uint32_t __unused keyIndex,
|
|
uint32_t* __unused outKeyLength, char* __unused outKey, bool* __unused outMandatory);
|
|
|
|
/**
|
|
* Descriptor: HWC2_FUNCTION_REGISTER_CALLBACK
|
|
* HWC2_PFN_REGISTER_CALLBACK
|
|
*/
|
|
int32_t registerCallback (
|
|
int32_t descriptor, hwc2_callback_data_t callbackData, hwc2_function_pointer_t point);
|
|
bool isCallbackAvailable(int32_t descriptor);
|
|
void onHotPlug(uint32_t displayId, bool status);
|
|
void onRefresh(uint32_t displayId);
|
|
void onRefreshDisplays();
|
|
|
|
void onVsync(uint32_t displayId, int64_t timestamp);
|
|
bool onVsync_2_4(uint32_t displayId, int64_t timestamp, uint32_t vsyncPeriod);
|
|
void onVsyncPeriodTimingChanged(uint32_t displayId,
|
|
hwc_vsync_period_change_timeline_t *timeline);
|
|
|
|
void setHWCDebug(unsigned int debug);
|
|
uint32_t getHWCDebug();
|
|
void setHWCFenceDebug(uint32_t ipNum, uint32_t typeNum, uint32_t mode);
|
|
void getHWCFenceDebug();
|
|
void setHWCControl(uint32_t display, uint32_t ctrl, int32_t val);
|
|
void setDisplayMode(uint32_t displayMode);
|
|
bool checkDisplayConnection(uint32_t displayId);
|
|
bool checkNonInternalConnection();
|
|
void getCapabilities(uint32_t *outCount, int32_t* outCapabilities);
|
|
void setGeometryChanged(uint64_t changedBit) { mGeometryChanged|= changedBit;};
|
|
void clearGeometryChanged();
|
|
void setDynamicRecomposition(uint32_t displayId, unsigned int on);
|
|
bool canSkipValidate();
|
|
bool validateFences(ExynosDisplay *display);
|
|
void compareVsyncPeriod();
|
|
bool isDynamicRecompositionThreadAlive();
|
|
void checkDynamicRecompositionThread();
|
|
int32_t setDisplayDeviceMode(int32_t display_id, int32_t mode);
|
|
int32_t setPanelGammaTableSource(int32_t display_id, int32_t type, int32_t source);
|
|
void dump(String8 &result);
|
|
|
|
class captureReadbackClass {
|
|
public:
|
|
captureReadbackClass(ExynosDevice *device);
|
|
~captureReadbackClass();
|
|
int32_t allocBuffer(uint32_t format, uint32_t w, uint32_t h);
|
|
buffer_handle_t& getBuffer() { return mBuffer; };
|
|
void saveToFile(const String8 &fileName);
|
|
private:
|
|
buffer_handle_t mBuffer = nullptr;
|
|
ExynosDevice* mDevice = nullptr;
|
|
};
|
|
void captureScreenWithReadback(uint32_t displayType);
|
|
void cleanupCaptureScreen(void *buffer);
|
|
void signalReadbackDone();
|
|
void clearWaitingReadbackReqDone() {
|
|
mIsWaitingReadbackReqDone = false;
|
|
};
|
|
|
|
uint32_t getWindowPlaneNum();
|
|
uint32_t getSpecialPlaneNum();
|
|
uint32_t getSpecialPlaneNum(uint32_t displayId);
|
|
uint32_t getSpecialPlaneId(uint32_t index);
|
|
uint64_t getSpecialPlaneAttr(uint32_t index);
|
|
|
|
int32_t registerHwc3Callback(uint32_t descriptor, hwc2_callback_data_t callbackData,
|
|
hwc2_function_pointer_t point);
|
|
void onVsyncIdle(hwc2_display_t displayId);
|
|
bool isDispOffAsyncSupported() { return mDisplayOffAsync; };
|
|
|
|
protected:
|
|
void initDeviceInterface(uint32_t interfaceType);
|
|
protected:
|
|
uint32_t mInterfaceType;
|
|
private:
|
|
Mutex mCaptureMutex;
|
|
Condition mCaptureCondition;
|
|
std::atomic<bool> mIsWaitingReadbackReqDone = false;
|
|
void setVBlankOffDelay(int vblankOffDelay);
|
|
bool isCallbackRegisteredLocked(int32_t descriptor);
|
|
|
|
public:
|
|
void enterToTUI() { mIsInTUI = true; };
|
|
void exitFromTUI() { mIsInTUI = false; };
|
|
bool isInTUI() { return mIsInTUI; };
|
|
|
|
private:
|
|
bool mIsInTUI;
|
|
bool mDisplayOffAsync;
|
|
};
|
|
|
|
#endif //_EXYNOSDEVICE_H
|