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; }
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; }
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); }
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; }
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; }