HWC 1.1: hook up hotplug event, use new display config queries
Change-Id: I2fd359e5fc7e1948072c6bc6b6fe47ea5e8025c1
This commit is contained in:
parent
9eb1eb5bb5
commit
1bd20e0f9e
@ -132,23 +132,21 @@ HWComposer::HWComposer(
|
||||
mCBContext->hwc = this;
|
||||
mCBContext->procs.invalidate = &hook_invalidate;
|
||||
mCBContext->procs.vsync = &hook_vsync;
|
||||
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
|
||||
mCBContext->procs.hotplug = &hook_hotplug;
|
||||
else
|
||||
mCBContext->procs.hotplug = NULL;
|
||||
memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
|
||||
mHwc->registerProcs(mHwc, &mCBContext->procs);
|
||||
}
|
||||
|
||||
// always turn vsync off when we start
|
||||
needVSyncThread = false;
|
||||
mHwc->eventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
|
||||
|
||||
int period;
|
||||
if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) {
|
||||
mDisplayData[HWC_DISPLAY_PRIMARY].refresh = nsecs_t(period);
|
||||
}
|
||||
mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
|
||||
|
||||
// these IDs are always reserved
|
||||
for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) {
|
||||
mAllocatedDisplayIDs.markBit(i);
|
||||
// TODO: we query xdpi / ydpi / refresh
|
||||
}
|
||||
|
||||
// the number of displays we actually have depends on the
|
||||
@ -166,7 +164,9 @@ HWComposer::HWComposer(
|
||||
}
|
||||
|
||||
if (fbDev) {
|
||||
// if we're here it means we are on version 1.0
|
||||
ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),
|
||||
"should only have fbdev if no hwc or hwc is 1.0");
|
||||
|
||||
DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);
|
||||
disp.xdpi = fbDev->xdpi;
|
||||
disp.ydpi = fbDev->ydpi;
|
||||
@ -176,8 +176,11 @@ HWComposer::HWComposer(
|
||||
}
|
||||
if (disp.refresh == 0) {
|
||||
disp.refresh = nsecs_t(1e9 / 60.0);
|
||||
ALOGW("getting VSYNC period thin air: %lld", mDisplayData[HWC_DISPLAY_PRIMARY].refresh);
|
||||
ALOGW("getting VSYNC period from thin air: %lld",
|
||||
mDisplayData[HWC_DISPLAY_PRIMARY].refresh);
|
||||
}
|
||||
} else if (mHwc) {
|
||||
queryDisplayProperties(HWC_DISPLAY_PRIMARY);
|
||||
}
|
||||
|
||||
if (needVSyncThread) {
|
||||
@ -207,24 +210,111 @@ void HWComposer::hook_invalidate(const struct hwc_procs* procs) {
|
||||
ctx->hwc->invalidate();
|
||||
}
|
||||
|
||||
void HWComposer::hook_vsync(const struct hwc_procs* procs, int dpy,
|
||||
void HWComposer::hook_vsync(const struct hwc_procs* procs, int disp,
|
||||
int64_t timestamp) {
|
||||
cb_context* ctx = reinterpret_cast<cb_context*>(
|
||||
const_cast<hwc_procs_t*>(procs));
|
||||
ctx->hwc->vsync(dpy, timestamp);
|
||||
ctx->hwc->vsync(disp, timestamp);
|
||||
}
|
||||
|
||||
void HWComposer::hook_hotplug(const struct hwc_procs* procs, int disp,
|
||||
int connected) {
|
||||
cb_context* ctx = reinterpret_cast<cb_context*>(
|
||||
const_cast<hwc_procs_t*>(procs));
|
||||
ctx->hwc->hotplug(disp, connected);
|
||||
}
|
||||
|
||||
void HWComposer::invalidate() {
|
||||
mFlinger->repaintEverything();
|
||||
}
|
||||
|
||||
void HWComposer::vsync(int dpy, int64_t timestamp) {
|
||||
void HWComposer::vsync(int disp, int64_t timestamp) {
|
||||
ATRACE_INT("VSYNC", ++mVSyncCount&1);
|
||||
mEventHandler.onVSyncReceived(dpy, timestamp);
|
||||
mEventHandler.onVSyncReceived(disp, timestamp);
|
||||
Mutex::Autolock _l(mLock);
|
||||
mLastHwVSync = timestamp;
|
||||
}
|
||||
|
||||
void HWComposer::hotplug(int disp, int connected) {
|
||||
if (disp == HWC_DISPLAY_PRIMARY || disp >= HWC_NUM_DISPLAY_TYPES) {
|
||||
ALOGE("hotplug event received for invalid display: disp=%d connected=%d",
|
||||
disp, connected);
|
||||
return;
|
||||
}
|
||||
|
||||
if (connected)
|
||||
queryDisplayProperties(disp);
|
||||
|
||||
// TODO: tell someone else about this
|
||||
}
|
||||
|
||||
static const uint32_t DISPLAY_ATTRIBUTES[] = {
|
||||
HWC_DISPLAY_VSYNC_PERIOD,
|
||||
HWC_DISPLAY_RESOLUTION_X,
|
||||
HWC_DISPLAY_RESOLUTION_Y,
|
||||
HWC_DISPLAY_DPI_X,
|
||||
HWC_DISPLAY_DPI_Y,
|
||||
HWC_DISPLAY_NO_ATTRIBUTE,
|
||||
};
|
||||
#define NUM_DISPLAY_ATTRIBUTES (sizeof(DISPLAY_ATTRIBUTES) / sizeof(DISPLAY_ATTRIBUTES)[0])
|
||||
|
||||
// http://developer.android.com/reference/android/util/DisplayMetrics.html
|
||||
#define ANDROID_DENSITY_TV 213
|
||||
#define ANDROID_DENSITY_XHIGH 320
|
||||
|
||||
void HWComposer::queryDisplayProperties(int disp) {
|
||||
ALOG_ASSERT(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
|
||||
|
||||
int32_t values[NUM_DISPLAY_ATTRIBUTES - 1];
|
||||
memset(values, 0, sizeof(values));
|
||||
|
||||
uint32_t config;
|
||||
size_t numConfigs = 1;
|
||||
status_t err = mHwc->getDisplayConfigs(mHwc, disp, &config, &numConfigs);
|
||||
if (err == NO_ERROR) {
|
||||
mHwc->getDisplayAttributes(mHwc, disp, config, DISPLAY_ATTRIBUTES,
|
||||
values);
|
||||
}
|
||||
|
||||
int32_t w = 0, h = 0;
|
||||
for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
|
||||
switch (DISPLAY_ATTRIBUTES[i]) {
|
||||
case HWC_DISPLAY_VSYNC_PERIOD:
|
||||
mDisplayData[disp].refresh = nsecs_t(values[i]);
|
||||
break;
|
||||
case HWC_DISPLAY_RESOLUTION_X:
|
||||
// TODO: we'll probably want to remember this eventually
|
||||
w = values[i];
|
||||
break;
|
||||
case HWC_DISPLAY_RESOLUTION_Y:
|
||||
// TODO: we'll probably want to remember this eventually
|
||||
h = values[i];
|
||||
break;
|
||||
case HWC_DISPLAY_DPI_X:
|
||||
mDisplayData[disp].xdpi = values[i] / 1000.0f;
|
||||
break;
|
||||
case HWC_DISPLAY_DPI_Y:
|
||||
mDisplayData[disp].ydpi = values[i] / 1000.0f;
|
||||
break;
|
||||
default:
|
||||
ALOG_ASSERT(false, "unknown display attribute %#x",
|
||||
DISPLAY_ATTRIBUTES[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mDisplayData[disp].xdpi == 0.0f || mDisplayData[disp].ydpi == 0.0f) {
|
||||
// is there anything smarter we can do?
|
||||
if (h >= 1080) {
|
||||
mDisplayData[disp].xdpi = ANDROID_DENSITY_XHIGH;
|
||||
mDisplayData[disp].ydpi = ANDROID_DENSITY_XHIGH;
|
||||
} else {
|
||||
mDisplayData[disp].xdpi = ANDROID_DENSITY_TV;
|
||||
mDisplayData[disp].ydpi = ANDROID_DENSITY_TV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t HWComposer::allocateDisplayId() {
|
||||
if (mAllocatedDisplayIDs.count() >= mNumDisplays) {
|
||||
return NO_MEMORY;
|
||||
|
@ -53,7 +53,7 @@ class HWComposer
|
||||
public:
|
||||
class EventHandler {
|
||||
friend class HWComposer;
|
||||
virtual void onVSyncReceived(int dpy, nsecs_t timestamp) = 0;
|
||||
virtual void onVSyncReceived(int disp, nsecs_t timestamp) = 0;
|
||||
protected:
|
||||
virtual ~EventHandler() {}
|
||||
};
|
||||
@ -242,12 +242,16 @@ private:
|
||||
struct cb_context;
|
||||
|
||||
static void hook_invalidate(const struct hwc_procs* procs);
|
||||
static void hook_vsync(const struct hwc_procs* procs, int dpy,
|
||||
static void hook_vsync(const struct hwc_procs* procs, int disp,
|
||||
int64_t timestamp);
|
||||
static void hook_hotplug(const struct hwc_procs* procs, int disp,
|
||||
int connected);
|
||||
|
||||
inline void invalidate();
|
||||
inline void vsync(int dpy, int64_t timestamp);
|
||||
inline void vsync(int disp, int64_t timestamp);
|
||||
inline void hotplug(int disp, int connected);
|
||||
|
||||
void queryDisplayProperties(int disp);
|
||||
|
||||
struct DisplayData {
|
||||
DisplayData() : xdpi(0), ydpi(0), refresh(0),
|
||||
|
Loading…
Reference in New Issue
Block a user