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;
}
void BufferManager::freeGrallocBuffer(uint32_t handle)
{
    RETURN_VOID_IF_NOT_INIT();
    if (!mGralloc) {
        WLOGTRACE("Alloc device is not available");
        return;
    }

    if (handle)
        gralloc_device_free_img(mGralloc, (buffer_handle_t)handle);
}
static int hwc_setActiveConfig(hwc_composer_device_1_t *dev, int disp, int index)
{
    ATRACE_CALL();
    GET_HWC_RETURN_ERROR_IF_NULL();
    bool ret = hwc->setActiveConfig(disp, index);
    if (ret == false) {
        WLOGTRACE("failed to set active config of disp %d", disp);
        return -EINVAL;
    }

    return 0;
}
static int hwc_getActiveConfig(hwc_composer_device_1_t *dev, int disp)
{
    ATRACE_CALL();
    GET_HWC_RETURN_ERROR_IF_NULL();
    int ret = hwc->getActiveConfig(disp);
    if (ret == -1) {
        WLOGTRACE("failed to get active config of disp %d", disp);
        return -EINVAL;
    }

    return ret;
}
static int hwc_setPowerMode(hwc_composer_device_1_t *dev, int disp, int mode)
{
    ATRACE_CALL();
    GET_HWC_RETURN_ERROR_IF_NULL();
    bool ret = hwc->setPowerMode(disp, mode);
    if (ret == false) {
        WLOGTRACE("failed to set power mode of disp %d", disp);
        return -EINVAL;
    }

    return 0;
}
static int hwc_setCursorPositionAsync(hwc_composer_device_1_t *dev, int disp, int x, int y)
{
    ATRACE_CALL();
    GET_HWC_RETURN_ERROR_IF_NULL();
    bool ret = hwc->setCursorPositionAsync(disp, x, y);
    if (ret == false) {
        WLOGTRACE("failed to set cursor position of disp %d", disp);
        return -EINVAL;
    }

    return 0;
}
static int hwc_getDisplayConfigs(hwc_composer_device_1_t *dev,
                                     int disp,
                                     uint32_t *configs,
                                     size_t *numConfigs)
{
    ATRACE_CALL();
    GET_HWC_RETURN_ERROR_IF_NULL();
    bool ret = hwc->getDisplayConfigs(disp, configs, numConfigs);
    if (ret == false) {
        WLOGTRACE("failed to get configs of disp %d", disp);
        return -EINVAL;
    }

    return 0;
}
static int hwc_getDisplayAttributes(hwc_composer_device_1_t *dev,
                                        int disp,
                                        uint32_t config,
                                        const uint32_t *attributes,
                                        int32_t *values)
{
    ATRACE_CALL();
    GET_HWC_RETURN_ERROR_IF_NULL();
    bool ret = hwc->getDisplayAttributes(disp, config, attributes, values);
    if (ret == false) {
        WLOGTRACE("failed to get attributes of disp %d", disp);
        return -EINVAL;
    }

    return 0;
}
bool Wsbm::initialize()
{
    if (mInitialized) {
        WLOGTRACE("object is initialized");
        return true;
    }

    int ret = psbWsbmInitialize(mDrmFD);
    if (ret) {
        ELOGTRACE("failed to initialize Wsbm");
        return false;
    }

    mInitialized = true;
    return true;
}
Beispiel #10
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 DisplayPlane::initialize(uint32_t bufferCount)
{
    CTRACE();

    if (bufferCount < MIN_DATA_BUFFER_COUNT) {
        WLOGTRACE("buffer count %d is too small", bufferCount);
        bufferCount = MIN_DATA_BUFFER_COUNT;
    }

    // create buffer cache, adding few extra slots as buffer rendering is async
    // buffer could still be queued in the display pipeline such that they
    // can't be unmapped]
    mCacheCapacity = bufferCount;
    mDataBuffers.setCapacity(bufferCount);
    mActiveBuffers.setCapacity(MIN_DATA_BUFFER_COUNT);
    mInitialized = true;
    return true;
}
Beispiel #12
0
bool Drm::initialize()
{
    if (mInitialized) {
        WLOGTRACE("Drm object has been initialized");
        return true;
    }

    const char *path = DrmConfig::getDrmPath();
    mDrmFd = open(path, O_RDWR, 0);
    if (mDrmFd < 0) {
        ELOGTRACE("failed to open Drm, error: %s", strerror(errno));
        return false;
    }
    DLOGTRACE("mDrmFd = %d", mDrmFd);

    memset(&mOutputs, 0, sizeof(mOutputs));
    mInitialized = true;
    return true;
}
void BufferManager::freeFrameBuffer(uint32_t fbHandle)
{
    RETURN_VOID_IF_NOT_INIT();

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

    ssize_t index = mFrameBuffers.indexOfKey(fbHandle);
    if (index < 0) {
        ELOGTRACE("invalid kernel handle");
        return;
    }

    BufferMapper *mapper = mFrameBuffers.valueAt(index);
    uint32_t handle = mapper->getHandle();
    mapper->putFbHandle();
    delete mapper;
    mFrameBuffers.removeItem(fbHandle);
    gralloc_device_free_img(mGralloc, (buffer_handle_t)handle);
}
Beispiel #14
0
bool Drm::readIoctl(unsigned long cmd, void *data,
                       unsigned long size)
{
    int err;

    if (mDrmFd <= 0) {
        ELOGTRACE("drm is not initialized");
        return false;
    }

    if (!data || !size) {
        ELOGTRACE("invalid parameters");
        return false;
    }

    err = drmCommandRead(mDrmFd, cmd, data, size);
    if (err) {
        WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err);
        return false;
    }

    return true;
}
static int hwc_eventControl(struct hwc_composer_device_1 *dev,
                                int disp,
                                int event,
                                int enabled)
{
    bool ret;
    ATRACE_CALL();
    GET_HWC_RETURN_ERROR_IF_NULL();

    switch (event) {
    case HWC_EVENT_VSYNC:
        ret = hwc->vsyncControl(disp, enabled);
        if (ret == false) {
            ELOGTRACE("failed to control vsync");
            return -EINVAL;
        }
        break;
    default:
        WLOGTRACE("unsupported event %d", event);
        break;
    }

    return 0;
}
uint32_t BufferManager::allocFrameBuffer(int width, int height, int *stride)
{
    RETURN_NULL_IF_NOT_INIT();

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

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

    ILOGTRACE("size of frame buffer to create: %dx%d", width, height);
    uint32_t handle = 0;
    status_t err = gralloc_device_alloc_img(
            mGralloc,
            width,
            height,
            DrmConfig::getFrameBufferFormat(),
            0, // GRALLOC_USAGE_HW_FB
            (buffer_handle_t *)&handle,
            stride);

    if (err != 0) {
        ELOGTRACE("failed to allocate frame buffer, error = %d", err);
        return 0;
    }

    DataBuffer *buffer = NULL;
    BufferMapper *mapper = NULL;

    do {
        buffer = lockDataBuffer(handle);
        if (!buffer) {
            ELOGTRACE("failed to get data buffer, handle = %#x", handle);
            break;
        }

        mapper = createBufferMapper(*buffer);
        if (!mapper) {
            ELOGTRACE("failed to create buffer mapper");
            break;
        }

        uint32_t fbHandle;
         if (!(fbHandle = mapper->getFbHandle(0))) {
             ELOGTRACE("failed to get Fb handle");
             break;
         }

        mFrameBuffers.add(fbHandle, mapper);
        unlockDataBuffer(buffer);
        return fbHandle;
    } while (0);

    // error handling, release all allocated resources
    if (buffer) {
        unlockDataBuffer(buffer);
    }
    if (mapper) {
        delete mapper;
    }
    gralloc_device_free_img(mGralloc, (buffer_handle_t)handle);
    return 0;
}
Beispiel #17
0
bool Drm::detect(int device)
{
    RETURN_FALSE_IF_NOT_INIT();

    Mutex::Autolock _l(mLock);
    int outputIndex = getOutputIndex(device);
    if (outputIndex < 0 ) {
        return false;
    }

    resetOutput(outputIndex);

    // get drm resources
    drmModeResPtr resources = drmModeGetResources(mDrmFd);
    if (!resources) {
        ELOGTRACE("fail to get drm resources, error: %s", strerror(errno));
        return false;
    }

    drmModeConnectorPtr connector = NULL;
    DrmOutput *output = &mOutputs[outputIndex];
    bool ret = false;

    // find connector for the given device
    for (int i = 0; i < resources->count_connectors; i++) {
        if (!resources->connectors || !resources->connectors[i]) {
            ELOGTRACE("fail to get drm resources connectors, error: %s", strerror(errno));
            continue;
        }

        connector = drmModeGetConnector(mDrmFd, resources->connectors[i]);
        if (!connector) {
            ELOGTRACE("drmModeGetConnector failed");
            continue;
        }

        if (connector->connector_type != DrmConfig::getDrmConnector(device)) {
            drmModeFreeConnector(connector);
            continue;
        }

        if (connector->connection != DRM_MODE_CONNECTED) {
            ILOGTRACE("device %d is not connected", device);
            drmModeFreeConnector(connector);
            ret = true;
            break;
        }

        output->connector = connector;
        output->connected = true;

        // get proper encoder for the given connector
        if (connector->encoder_id) {
            ILOGTRACE("Drm connector has encoder attached on device %d", device);
            output->encoder = drmModeGetEncoder(mDrmFd, connector->encoder_id);
            if (!output->encoder) {
                ELOGTRACE("failed to get encoder from a known encoder id");
                // fall through to get an encoder
            }
        }
        if (!output->encoder) {
            ILOGTRACE("getting encoder for device %d", device);
            drmModeEncoderPtr encoder;
            for (int j = 0; j < resources->count_encoders; j++) {
                if (!resources->encoders || !resources->encoders[j]) {
                    ELOGTRACE("fail to get drm resources encoders, error: %s", strerror(errno));
                    continue;
                }

                encoder = drmModeGetEncoder(mDrmFd, resources->encoders[i]);
                if (!encoder) {
                    ELOGTRACE("drmModeGetEncoder failed");
                    continue;
                }
                if (encoder->encoder_type == DrmConfig::getDrmEncoder(device)) {
                    output->encoder = encoder;
                    break;
                }
                drmModeFreeEncoder(encoder);
                encoder = NULL;
            }
        }
        if (!output->encoder) {
            ELOGTRACE("failed to get drm encoder");
            break;
        }

        // get an attached crtc or spare crtc
        if (output->encoder->crtc_id) {
            ILOGTRACE("Drm encoder has crtc attached on device %d", device);
            output->crtc = drmModeGetCrtc(mDrmFd, output->encoder->crtc_id);
            if (!output->crtc) {
                ELOGTRACE("failed to get crtc from a known crtc id");
                // fall through to get a spare crtc
            }
        }
        if (!output->crtc) {
            ILOGTRACE("getting crtc for device %d", device);
            drmModeCrtcPtr crtc;
            for (int j = 0; j < resources->count_crtcs; j++) {
                if (!resources->crtcs || !resources->crtcs[j]) {
                    ELOGTRACE("fail to get drm resources crtcs, error: %s", strerror(errno));
                    continue;
                }

                crtc = drmModeGetCrtc(mDrmFd, resources->crtcs[j]);
                if (!crtc) {
                    ELOGTRACE("drmModeGetCrtc failed");
                    continue;
                }
                // check if legal crtc to the encoder
                if (output->encoder->possible_crtcs & (1<<j)) {
                    if (crtc->buffer_id == 0) {
                        output->crtc = crtc;
                        break;
                    }
                }
                drmModeFreeCrtc(crtc);
            }
        }
        if (!output->crtc) {
            ELOGTRACE("failed to get drm crtc");
            break;
        }

        // current mode
        if (output->crtc->mode_valid) {
            ILOGTRACE("mode is valid, kernel mode settings");
            memcpy(&output->mode, &output->crtc->mode, sizeof(drmModeModeInfo));
            //output->fbId = output->crtc->buffer_id;
            ret = true;
        } else {
            ELOGTRACE("mode is invalid. Kernel mode setting is not completed");
            ret = false;
        }

        if (outputIndex == OUTPUT_PRIMARY) {
            if (!readIoctl(DRM_PSB_PANEL_ORIENTATION, &output->panelOrientation, sizeof(int))) {
                ELOGTRACE("failed to get device %d orientation", device);
                output->panelOrientation = PANEL_ORIENTATION_0;
            }
        } else {
            output->panelOrientation = PANEL_ORIENTATION_0;
        }
        break;
    }

    if (!ret) {
        if (output->connector == NULL && outputIndex != OUTPUT_PRIMARY) {
            // a fatal failure on primary device
            // non fatal on secondary device
            WLOGTRACE("device %d is disabled?", device);
            ret = true;
        }
         resetOutput(outputIndex);
    } else if (output->connected) {
        ILOGTRACE("mode is: %dx%d@%dHz", output->mode.hdisplay, output->mode.vdisplay, output->mode.vrefresh);
    }

    drmModeFreeResources(resources);
    return ret;
}
bool DisplayPlane::setDataBuffer(uint32_t handle)
{
    DataBuffer *buffer;
    BufferMapper *mapper;
    ssize_t index;
    bool ret;
    bool isCompression;
    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();

    RETURN_FALSE_IF_NOT_INIT();
    ALOGTRACE("handle = %#x", handle);

    if (!handle) {
        WLOGTRACE("invalid buffer handle");
        return false;
    }

    // do not need to update the buffer handle
    if (mCurrentDataBuffer != handle)
        mUpdateMasks |= PLANE_BUFFER_CHANGED;

    // if no update then do Not need set data buffer
    if (!mUpdateMasks)
        return true;

    buffer = bm->lockDataBuffer(handle);
    if (!buffer) {
        ELOGTRACE("failed to get buffer");
        return false;
    }

    mIsProtectedBuffer = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer);
    isCompression = GraphicBuffer::isCompressionBuffer((GraphicBuffer*)buffer);

    // map buffer if it's not in cache
    index = mDataBuffers.indexOfKey(buffer->getKey());
    if (index < 0) {
        VLOGTRACE("unmapped buffer, mapping...");
        mapper = mapBuffer(buffer);
        if (!mapper) {
            ELOGTRACE("failed to map buffer %#x", handle);
            bm->unlockDataBuffer(buffer);
            return false;
        }
    } else {
        VLOGTRACE("got mapper in saved data buffers and update source Crop");
        mapper = mDataBuffers.valueAt(index);
    }

    // always update source crop to mapper
    mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h);

    mapper->setIsCompression(isCompression);

    // unlock buffer after getting mapper
    bm->unlockDataBuffer(buffer);
    buffer = NULL;

    ret = setDataBuffer(*mapper);
    if (ret) {
        mCurrentDataBuffer = handle;
        // update active buffers
        updateActiveBuffers(mapper);
    }
    return ret;
}