uint32_t BufferManager::allocGrallocBuffer(uint32_t width, uint32_t height, uint32_t format, uint32_t usage)
{
    RETURN_NULL_IF_NOT_INIT();

    if (!mGralloc) {
        WLOGTRACE("Alloc device is not available");
        return 0;
    }

    if (!width || !height) {
        ELOGTRACE("invalid input parameter");
        return 0;
    }

    ILOGTRACE("size of graphic buffer to create: %dx%d", width, height);
    uint32_t handle = 0;
    int stride;
    status_t err = gralloc_device_alloc_img(
                mGralloc,
                width,
                height,
                format,
                usage,
                (buffer_handle_t *)&handle,
                &stride);
    if (err != 0) {
        ELOGTRACE("failed to allocate gralloc buffer, error = %d", err);
        return 0;
    }

    return handle;
}
Example #2
0
// HWC 1.4 requires that we return all of the compatible configs in getDisplayConfigs
// this is needed so getActiveConfig/setActiveConfig work correctly.  It is up to the
// user space to decide what speed to send.
drmModeModeInfoPtr Drm::detectAllConfigs(int device, int *modeCount)
{
    RETURN_NULL_IF_NOT_INIT();
    Mutex::Autolock _l(mLock);

    if (modeCount != NULL)
        *modeCount = 0;
    else
        return NULL;

    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0) {
        ELOGTRACE("invalid device");
        return NULL;
    }

    DrmOutput *output= &mOutputs[outputIndex];
    if (!output->connected) {
        ELOGTRACE("device is not connected");
        return NULL;
    }

    if (output->connector->count_modes <= 0) {
        ELOGTRACE("invalid count of modes");
        return NULL;
    }

    *modeCount = output->connector->count_modes;
    return output->connector->modes;
}
Example #3
0
bool Drm::getModeInfo(int device, drmModeModeInfo& mode)
{
    Mutex::Autolock _l(mLock);

    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0 ) {
        return false;
    }

    DrmOutput *output= &mOutputs[outputIndex];
    if (output->connected == false) {
        ELOGTRACE("device is not connected");
        return false;
    }

    if (output->mode.hdisplay == 0 || output->mode.vdisplay == 0) {
        ELOGTRACE("invalid width or height");
        return false;
    }

    memcpy(&mode, &output->mode, sizeof(drmModeModeInfo));

#ifdef INTEL_SUPPORT_HDMI_PRIMARY
    // FIXME: use default fb size instead of hdmi mode, because to
    // support hdmi primary, we cannot report dynamic mode to SF.
    mode.hdisplay = DEFAULT_DRM_FB_WIDTH;
    mode.vdisplay = DEFAULT_DRM_FB_HEIGHT;
#endif

    return true;
}
BufferMapper* DisplayPlane::mapBuffer(DataBuffer *buffer)
{
    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();

    // invalidate buffer cache  if cache is full
    if ((int)mDataBuffers.size() >= mCacheCapacity) {
        invalidateBufferCache();
    }

    BufferMapper *mapper = bm->map(*buffer);
    if (!mapper) {
        ELOGTRACE("failed to map buffer");
        return NULL;
    }

    // add it to data buffers
    ssize_t index = mDataBuffers.add(buffer->getKey(), mapper);
    if (index < 0) {
        ELOGTRACE("failed to add mapper");
        bm->unmap(mapper);
        return NULL;
    }

    return mapper;
}
static int hwc_device_open(const struct hw_module_t* module,
                              const char* name,
                              struct hw_device_t** device)
{
    if (!name) {
        ELOGTRACE("invalid name.");
        return -EINVAL;
    }

    ALOGTRACE("open device %s", name);

    if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
        ELOGTRACE("try to open unknown HWComposer %s", name);
        return -EINVAL;
    }

    Hwcomposer& hwc = Hwcomposer::getInstance();
    // initialize our state here
    if (hwc.initialize() == false) {
        ELOGTRACE("failed to intialize HWComposer");
        Hwcomposer::releaseInstance();
        return -EINVAL;
    }

    // initialize the procs
    hwc.hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG;
    hwc.hwc_composer_device_1_t::common.module =
        const_cast<hw_module_t*>(module);
    hwc.hwc_composer_device_1_t::common.close = hwc_device_close;

    hwc.hwc_composer_device_1_t::prepare = hwc_prepare;
    hwc.hwc_composer_device_1_t::set = hwc_set;
    hwc.hwc_composer_device_1_t::dump = hwc_dump;
    hwc.hwc_composer_device_1_t::registerProcs = hwc_registerProcs;
    hwc.hwc_composer_device_1_t::query = hwc_query;

    hwc.hwc_composer_device_1_t::eventControl = hwc_eventControl;
    hwc.hwc_composer_device_1_t::getDisplayConfigs = hwc_getDisplayConfigs;
    hwc.hwc_composer_device_1_t::getDisplayAttributes = hwc_getDisplayAttributes;

    // This is used to hack FBO switch flush issue in SurfaceFlinger.
    hwc.hwc_composer_device_1_t::reserved_proc[0] = (void*)hwc_compositionComplete;
    hwc.hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_4;
    hwc.hwc_composer_device_1_t::setPowerMode = hwc_setPowerMode;
    hwc.hwc_composer_device_1_t::getActiveConfig = hwc_getActiveConfig;
    hwc.hwc_composer_device_1_t::setActiveConfig = hwc_setActiveConfig;
    // Todo: add hwc_setCursorPositionAsync after supporting patches
    hwc.hwc_composer_device_1_t::setCursorPositionAsync = NULL;

    *device = &hwc.hwc_composer_device_1_t::common;

    return 0;
}
Example #6
0
bool Drm::setDpmsMode(int device, int mode)
{
    Mutex::Autolock _l(mLock);

    int output = getOutputIndex(device);
    if (output < 0 ) {
        return false;
    }

    if (mode != IDisplayDevice::DEVICE_DISPLAY_OFF &&
            mode != IDisplayDevice::DEVICE_DISPLAY_STANDBY &&
            mode != IDisplayDevice::DEVICE_DISPLAY_ON) {
        ELOGTRACE("invalid mode %d", mode);
        return false;
    }

    DrmOutput *out = &mOutputs[output];
    if (!out->connected) {
        ELOGTRACE("device is not connected");
        return false;
    }

    drmModePropertyPtr props;
    for (int i = 0; i < out->connector->count_props; i++) {
        props = drmModeGetProperty(mDrmFd, out->connector->props[i]);
        if (!props) {
            continue;
        }

        if (strcmp(props->name, "DPMS") == 0) {
            int ret = drmModeConnectorSetProperty(
                mDrmFd,
                out->connector->connector_id,
                props->prop_id,
                (mode == IDisplayDevice::DEVICE_DISPLAY_ON) ? DRM_MODE_DPMS_ON :
                        IDisplayDevice::DEVICE_DISPLAY_STANDBY == mode ?
                        DRM_MODE_DPMS_STANDBY : DRM_MODE_DPMS_OFF);
            drmModeFreeProperty(props);
            if (ret != 0) {
                ELOGTRACE("unable to set DPMS %d", mode);
                return false;
            } else {
                return true;
            }
        }
        drmModeFreeProperty(props);
    }
    return false;
}
bool BufferManager::initialize()
{
    CTRACE();

    // create buffer pool
    mBufferPool = new BufferCache(DEFAULT_BUFFER_POOL_SIZE);
    if (!mBufferPool) {
        ELOGTRACE("failed to create gralloc buffer cache");
        return false;
    }

    // init gralloc module
    if (gralloc_open_img(&mGralloc)) {
        DEINIT_AND_RETURN_FALSE("failed to get gralloc module");
    }

    // create a dummy data buffer
    mDataBuffer = createDataBuffer(0);
    if (!mDataBuffer) {
        DEINIT_AND_RETURN_FALSE("failed to create data buffer");
    }

    mInitialized = true;
    return true;
}
bool TngGrallocBufferMapper::gttMap(void *vaddr,
                                      uint32_t size,
                                      uint32_t gttAlign,
                                      int *offset)
{
    struct psb_gtt_mapping_arg arg;
    bool ret;

    ALOGTRACE("vaddr = %p, size = %d", vaddr, size);

    if (!vaddr || !size || !offset) {
        VLOGTRACE("invalid parameters");
        return false;
    }

    arg.type = PSB_GTT_MAP_TYPE_VIRTUAL;
    arg.page_align = gttAlign;
    arg.vaddr = (uint32_t)vaddr;
    arg.size = size;

    Drm *drm = Hwcomposer::getInstance().getDrm();
    ret = drm->writeReadIoctl(DRM_PSB_GTT_MAP, &arg, sizeof(arg));
    if (ret == false) {
        ELOGTRACE("gtt mapping failed");
        return false;
    }

    VLOGTRACE("offset = %#x", arg.offset_pages);
    *offset =  arg.offset_pages;
    return true;
}
bool DisplayPlane::assignToDevice(int disp)
{
    RETURN_FALSE_IF_NOT_INIT();
    ALOGTRACE("disp = %d", disp);

    mDevice = disp;

    Drm *drm = Hwcomposer::getInstance().getDrm();
    if (!drm->getModeInfo(mDevice, mModeInfo)) {
        ELOGTRACE("failed to get mode info");
    }

    mPanelOrientation = drm->getPanelOrientation(mDevice);

    mForceScaling = DisplayQuery::forceFbScaling(disp);
    drm->getDisplayResolution(disp, mDisplayWidth, mDisplayHeight);

    if (mForceScaling) {
        mModeInfo.hdisplay = mDisplayWidth;
        mModeInfo.vdisplay = mDisplayHeight;
        mPosition.x = 0;
        mPosition.y = 0;
        mPosition.w = mDisplayWidth;
        mPosition.h = mDisplayHeight;
    }
    mDisplayCrop.x = 0;
    mDisplayCrop.y = 0;
    mDisplayCrop.w = mDisplayWidth;
    mDisplayCrop.h = mDisplayHeight;

    return true;
}
Example #10
0
int Drm::getPanelOrientation(int device)
{
    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0) {
        ELOGTRACE("invalid device");
        return PANEL_ORIENTATION_0;
    }

    DrmOutput *output= &mOutputs[outputIndex];
    if (output->connected == false) {
        ELOGTRACE("device is not connected");
        return PANEL_ORIENTATION_0;
    }

    return output->panelOrientation;
}
BufferMapper* BufferManager::map(DataBuffer& buffer)
{
    bool ret;
    BufferMapper* mapper;

    CTRACE();
    Mutex::Autolock _l(mLock);
    //try to get mapper from pool
    mapper = mBufferPool->getMapper(buffer.getKey());
    if (mapper) {
        // increase mapper ref count
        mapper->incRef();
        return mapper;
    }

    // create a new buffer mapper and add it to pool
    do {
        VLOGTRACE("new buffer, will add it");
        mapper = createBufferMapper(buffer);
        if (!mapper) {
            ELOGTRACE("failed to allocate mapper");
            break;
        }
        ret = mapper->map();
        if (!ret) {
            ELOGTRACE("failed to map");
            delete mapper;
            mapper = NULL;
            break;
        }
        ret = mBufferPool->addMapper(buffer.getKey(), mapper);
        if (!ret) {
            ELOGTRACE("failed to add mapper");
            break;
        }
        // increase mapper ref count
        mapper->incRef();
        return mapper;
    } while (0);

    // error handling
    if (mapper) {
        mapper->unmap();
        delete mapper;
    }
    return NULL;
}
bool Hwcomposer::setActiveConfig(int disp, int index)
{
    RETURN_FALSE_IF_NOT_INIT();

    if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
        ELOGTRACE("invalid disp %d", disp);
        return false;
    }

    IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    if (!device) {
        ELOGTRACE("no device found");
        return false;
    }

    return device->setActiveConfig(index);
}
int Hwcomposer::getActiveConfig(int disp)
{
    RETURN_NULL_IF_NOT_INIT();

    if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
        ELOGTRACE("invalid disp %d", disp);
        return -1;
    }

    IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    if (!device) {
        ELOGTRACE("no device found");
        return -1;
    }

    return device->getActiveConfig();
}
Example #14
0
bool Drm::setRefreshRate(int device, int hz)
{
    RETURN_FALSE_IF_NOT_INIT();
    Mutex::Autolock _l(mLock);

    if (device != IDisplayDevice::DEVICE_EXTERNAL) {
        WLOGTRACE("Setting mode on invalid device %d", device);
        return false;
    }

    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0 ) {
        ELOGTRACE("invalid device");
        return false;
    }

    DrmOutput *output= &mOutputs[outputIndex];
    if (!output->connected) {
        ELOGTRACE("device is not connected");
        return false;
    }

    if (output->connector->count_modes <= 0) {
        ELOGTRACE("invalid count of modes");
        return false;
    }

    drmModeModeInfoPtr mode;
    int index = 0;
    for (int i = 0; i < output->connector->count_modes; i++) {
        mode = &output->connector->modes[i];
        if (mode->type & DRM_MODE_TYPE_PREFERRED) {
            index = i;
        }
        if (mode->hdisplay == output->mode.hdisplay &&
            mode->vdisplay == output->mode.vdisplay &&
            mode->vrefresh == (uint32_t)hz) {
            index = i;
            break;
        }
    }

    mode = &output->connector->modes[index];
    return setDrmMode(outputIndex, mode);
}
bool Wsbm::wrapTTMBuffer(uint32_t handle, void **buf)
{
    int ret = psbWsbmWrapTTMBuffer(handle, buf);
    if (ret) {
        ELOGTRACE("failed to wrap buffer");
        return false;
    }

    return true;
}
bool Wsbm::destroyTTMBuffer(void * buf)
{
    int ret = psbWsbmDestroyTTMBuffer(buf);
    if (ret) {
        ELOGTRACE("failed to destroy buffer");
        return false;
    }

    return true;
}
bool Wsbm::allocateTTMBufferUB(uint32_t size, uint32_t align, void ** buf, void *user_pt)
{
    int ret = psbWsbmAllocateFromUB(size, align, buf, user_pt);
    if (ret) {
        ELOGTRACE("failed to allocate UB buffer");
        return false;
    }

    return true;
}
bool Wsbm::allocateTTMBuffer(uint32_t size, uint32_t align, void ** buf)
{
    int ret = psbWsbmAllocateTTMBuffer(size, align, buf);
    if (ret) {
        ELOGTRACE("failed to allocate buffer");
        return false;
    }

    return true;
}
bool Wsbm::waitIdleTTMBuffer(void *buf)
{
    int ret = psbWsbmWaitIdle(buf);
    if (ret) {
        ELOGTRACE("failed to wait ttm buffer for idle");
        return false;
    }

    return true;
}
bool Wsbm::unreferenceTTMBuffer(void *buf)
{
    int ret = psbWsbmUnReference(buf);
    if (ret) {
        ELOGTRACE("failed to unreference buffer");
        return false;
    }

    return true;
}
void TngGrallocBufferMapper::putFbHandle()
{
    int err = mIMGGrallocModule.putCpuAddress(&mIMGGrallocModule,
                                    (buffer_handle_t)getHandle());
    if (err) {
        ELOGTRACE("failed to unmap. err = %d", err);
    }
    return;

}
void BufferManager::unmap(BufferMapper *mapper)
{
    Mutex::Autolock _l(mLock);
    if (!mapper) {
        ELOGTRACE("invalid mapper");
        return;
    }

    // unmap & remove this mapper from buffer when refCount = 0
    int refCount = mapper->decRef();
    if (refCount < 0) {
        ELOGTRACE("invalid ref count");
    } else if (!refCount) {
        // remove mapper from buffer pool
        mBufferPool->removeMapper(mapper);
        mapper->unmap();
        delete mapper;
    }
}
bool Hwcomposer::blank(int disp, int blank)
{
    RETURN_FALSE_IF_NOT_INIT();
    ALOGTRACE("disp = %d, blank = %d", disp, blank);

    if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
        ELOGTRACE("invalid disp %d", disp);
        return false;
    }
    if (disp >= (int) mDisplayDevices.size()) {
        return false;
    }
    IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    if (!device) {
        ELOGTRACE("no device found");
        return false;
    }

    return device->blank(blank ? true : false);
}
bool Hwcomposer::vsyncControl(int disp, int enabled)
{
    RETURN_FALSE_IF_NOT_INIT();
    ALOGTRACE("disp = %d, enabled = %d", disp, enabled);

    if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
        ELOGTRACE("invalid disp %d", disp);
        return false;
    }
    if (disp >= (int) mDisplayDevices.size()) {
        return false;
    }
    IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    if (!device) {
        ELOGTRACE("no device found");
        return false;
    }

    return device->vsyncControl(enabled ? true : false);
}
bool Hwcomposer::setCursorPositionAsync(int disp, int x, int y)
{
    RETURN_FALSE_IF_NOT_INIT();

    if (disp != HWC_DISPLAY_PRIMARY && disp != HWC_DISPLAY_EXTERNAL) {
        ELOGTRACE("invalid disp %d", disp);
        return false;
    }

    return mDisplayContext->setCursorPosition(disp, x, y);
}
bool TngGrallocBufferMapper::map()
{
    void *vaddr[SUB_BUFFER_MAX];
    uint32_t size[SUB_BUFFER_MAX];
    int gttOffsetInPage = 0;
    bool ret;
    int err;
    int i;

    CTRACE();
    // get virtual address
    err = mIMGGrallocModule.getCpuAddress(&mIMGGrallocModule,
                                          (buffer_handle_t)getHandle(),
                                          vaddr,
                                          size);
    if (err) {
        ELOGTRACE("failed to map. err = %d", err);
        return false;
    }

    for (i = 0; i < SUB_BUFFER_MAX; i++) {
        // skip gtt mapping for empty sub buffers
        if (!vaddr[i] || !size[i])
            continue;

        // map to gtt
        ret = gttMap(vaddr[i], size[i], 0, &gttOffsetInPage);
        if (!ret) {
            VLOGTRACE("failed to map %d into gtt", i);
            break;
        }

        mCpuAddress[i] = vaddr[i];
        mSize[i] = size[i];
        mGttOffsetInPage[i] = gttOffsetInPage;
        // TODO:  set kernel handle
        mKHandle[i] = 0;
    }

    if (i == SUB_BUFFER_MAX) {
        return true;
    }

    // error handling
    for (i = 0; i < SUB_BUFFER_MAX; i++) {
        if (mCpuAddress[i]) {
            gttUnmap(mCpuAddress[i]);
        }
    }

    err = mIMGGrallocModule.putCpuAddress(&mIMGGrallocModule,
                                    (buffer_handle_t)getHandle());
    return false;
}
Example #27
0
bool Hwcomposer::setActiveConfig(int disp, int index)
{
    RETURN_FALSE_IF_NOT_INIT();

    if (disp != 0) {
        ELOGTRACE("invalid disp %d", disp);
//         return false;
    }

//     return device->setActiveConfig(index);
    return true;
}
Example #28
0
int Hwcomposer::getActiveConfig(int disp)
{
    RETURN_NULL_IF_NOT_INIT();

    if (disp != 0) {
        ELOGTRACE("invalid disp %d", disp);
        return -1;
    }

//     return device->getActiveConfig();
    return 0;
}
Example #29
0
bool Hwcomposer::setPowerMode(int disp, int mode)
{
    RETURN_FALSE_IF_NOT_INIT();

    if (disp != 0) {
        ELOGTRACE("invalid disp %d", disp);
//         return false;
    }

//     return device->setPowerMode(mode);
    return true;
}
bool TngGrallocBufferMapper::mapKhandle()
{
    // TODO: this is a complete hack and temporary workaround
    // need support from DDK to map khandle
    void *wsbmBufferObject = 0;
    int ret = psbWsbmWrapTTMBuffer2(mHandle, &wsbmBufferObject);
    if (ret != 0) {
        ELOGTRACE("Wrap ttm buffer failed!");
        return false;
    }

    ret = psbWsbmCreateFromUB(wsbmBufferObject, mWidth * mHeight, mCpuAddress[0]);
    if (ret != 0) {
        ELOGTRACE("Create from UB failed!");
        return false;
    }

    mKHandle[0] = psbWsbmGetKBufHandle(wsbmBufferObject);
    psbWsbmUnReference(wsbmBufferObject);
    return true;
}