Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f90883d6 authored by Jesse Hall's avatar Jesse Hall Committed by Android (Google) Code Review
Browse files

Merge "HWC 1.1: hook up hotplug event, use new display config queries" into jb-mr1-dev

parents 4697528e 1bd20e0f
Loading
Loading
Loading
Loading
+103 −13
Original line number Original line Diff line number Diff line
@@ -132,23 +132,21 @@ HWComposer::HWComposer(
                mCBContext->hwc = this;
                mCBContext->hwc = this;
                mCBContext->procs.invalidate = &hook_invalidate;
                mCBContext->procs.invalidate = &hook_invalidate;
                mCBContext->procs.vsync = &hook_vsync;
                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));
                memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
                mHwc->registerProcs(mHwc, &mCBContext->procs);
                mHwc->registerProcs(mHwc, &mCBContext->procs);
            }
            }


            // always turn vsync off when we start
            // always turn vsync off when we start
            needVSyncThread = false;
            needVSyncThread = false;
            mHwc->eventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
            mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);

            int period;
            if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) {
                mDisplayData[HWC_DISPLAY_PRIMARY].refresh = nsecs_t(period);
            }


            // these IDs are always reserved
            // these IDs are always reserved
            for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) {
            for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) {
                mAllocatedDisplayIDs.markBit(i);
                mAllocatedDisplayIDs.markBit(i);
                // TODO: we query xdpi / ydpi / refresh
            }
            }


            // the number of displays we actually have depends on the
            // the number of displays we actually have depends on the
@@ -166,7 +164,9 @@ HWComposer::HWComposer(
    }
    }


    if (fbDev) {
    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]);
        DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);
        disp.xdpi = fbDev->xdpi;
        disp.xdpi = fbDev->xdpi;
        disp.ydpi = fbDev->ydpi;
        disp.ydpi = fbDev->ydpi;
@@ -176,8 +176,11 @@ HWComposer::HWComposer(
        }
        }
        if (disp.refresh == 0) {
        if (disp.refresh == 0) {
            disp.refresh = nsecs_t(1e9 / 60.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) {
    if (needVSyncThread) {
@@ -207,24 +210,111 @@ void HWComposer::hook_invalidate(const struct hwc_procs* procs) {
    ctx->hwc->invalidate();
    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) {
        int64_t timestamp) {
    cb_context* ctx = reinterpret_cast<cb_context*>(
    cb_context* ctx = reinterpret_cast<cb_context*>(
            const_cast<hwc_procs_t*>(procs));
            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() {
void HWComposer::invalidate() {
    mFlinger->repaintEverything();
    mFlinger->repaintEverything();
}
}


void HWComposer::vsync(int dpy, int64_t timestamp) {
void HWComposer::vsync(int disp, int64_t timestamp) {
    ATRACE_INT("VSYNC", ++mVSyncCount&1);
    ATRACE_INT("VSYNC", ++mVSyncCount&1);
    mEventHandler.onVSyncReceived(dpy, timestamp);
    mEventHandler.onVSyncReceived(disp, timestamp);
    Mutex::Autolock _l(mLock);
    Mutex::Autolock _l(mLock);
    mLastHwVSync = timestamp;
    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() {
int32_t HWComposer::allocateDisplayId() {
    if (mAllocatedDisplayIDs.count() >= mNumDisplays) {
    if (mAllocatedDisplayIDs.count() >= mNumDisplays) {
        return NO_MEMORY;
        return NO_MEMORY;
+7 −3
Original line number Original line Diff line number Diff line
@@ -53,7 +53,7 @@ class HWComposer
public:
public:
    class EventHandler {
    class EventHandler {
        friend class HWComposer;
        friend class HWComposer;
        virtual void onVSyncReceived(int dpy, nsecs_t timestamp) = 0;
        virtual void onVSyncReceived(int disp, nsecs_t timestamp) = 0;
    protected:
    protected:
        virtual ~EventHandler() {}
        virtual ~EventHandler() {}
    };
    };
@@ -242,12 +242,16 @@ private:
    struct cb_context;
    struct cb_context;


    static void hook_invalidate(const struct hwc_procs* procs);
    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);
            int64_t timestamp);
    static void hook_hotplug(const struct hwc_procs* procs, int disp,
            int connected);


    inline void invalidate();
    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 {
    struct DisplayData {
        DisplayData() : xdpi(0), ydpi(0), refresh(0),
        DisplayData() : xdpi(0), ydpi(0), refresh(0),