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; }
bool OverlayPlaneBase::assignToDevice(int disp) { uint32_t pipeConfig = 0; RETURN_FALSE_IF_NOT_INIT(); VTRACE("overlay %d assigned to disp %d", mIndex, disp); switch (disp) { case IDisplayDevice::DEVICE_EXTERNAL: pipeConfig = (0x2 << 6); break; case IDisplayDevice::DEVICE_PRIMARY: default: pipeConfig = 0; break; } // if pipe switching happened, then disable overlay first if (mPipeConfig != pipeConfig) { DTRACE("overlay %d switched from %d to %d", mIndex, mDevice, disp); disable(); } mPipeConfig = pipeConfig; DisplayPlane::assignToDevice(disp); enable(); return true; }
bool TngDisplayContext::commitBegin(size_t /* numDisplays */, hwc_display_contents_1_t ** /* displays */) { RETURN_FALSE_IF_NOT_INIT(); mCount = 0; return true; }
bool TngSpritePlane::enablePlane(bool enabled) { RETURN_FALSE_IF_NOT_INIT(); struct drm_psb_register_rw_arg arg; memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); if (enabled) { arg.plane_enable_mask = 1; } else { arg.plane_disable_mask = 1; } arg.plane.type = DC_SPRITE_PLANE; arg.plane.index = mIndex; arg.plane.ctx = 0; // issue ioctl Drm *drm = Hwcomposer::getInstance().getDrm(); bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); if (ret == false) { WTRACE("sprite enabling (%d) failed with error code %d", enabled, ret); return false; } Hwcomposer& hwc = Hwcomposer::getInstance(); DisplayPlaneManager *pm = hwc.getPlaneManager(); void *config = pm->getZOrderConfig(); if (config != NULL) { struct intel_dc_plane_zorder *zorder = (struct intel_dc_plane_zorder *)config; zorder->abovePrimary = 0; } return true; }
bool TngSpritePlane::isDisabled() { RETURN_FALSE_IF_NOT_INIT(); struct drm_psb_register_rw_arg arg; memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); if (mType == DisplayPlane::PLANE_SPRITE) arg.plane.type = DC_SPRITE_PLANE; else arg.plane.type = DC_PRIMARY_PLANE; arg.get_plane_state_mask = 1; arg.plane.index = mIndex; arg.plane.ctx = 0; // issue ioctl Drm *drm = Hwcomposer::getInstance().getDrm(); bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); if (ret == false) { WTRACE("plane state query failed with error code %d", ret); return false; } return arg.plane.ctx == PSB_DC_PLANE_DISABLED; }
bool DisplayPlane::flip(void * /* ctx */) { RETURN_FALSE_IF_NOT_INIT(); // always flip return true; }
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 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 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; }
bool Hwcomposer::vsyncControl(int disp, int enabled) { RETURN_FALSE_IF_NOT_INIT(); ALOGTRACE("disp = %d, enabled = %d", disp, enabled); if (disp != 0) { ELOGTRACE("invalid disp %d", disp); // return false; } // return device->vsyncControl(enabled ? true : false); return true; }
bool Hwcomposer::getDisplayConfigs(int disp, uint32_t *configs, size_t *numConfigs) { RETURN_FALSE_IF_NOT_INIT(); if (disp != 0) { ELOGTRACE("invalid disp %d", disp); // return false; } // return device->getDisplayConfigs(configs, numConfigs); return true; }
bool Hwcomposer::compositionComplete(int disp) { RETURN_FALSE_IF_NOT_INIT(); if (disp != 0) { ELOGTRACE("invalid disp %d", disp); // return false; } // mDisplayContext->compositionComplete(); // return device->compositionComplete(); return true; }
bool Hwcomposer::getDisplayAttributes(int disp, uint32_t config, const uint32_t *attributes, int32_t *values) { RETURN_FALSE_IF_NOT_INIT(); if (disp != 0) { ELOGTRACE("invalid disp %d", disp); // return false; } // return device->getDisplayAttributes(config, attributes, values); return true; }
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); }
bool OverlayPlaneBase::reset() { RETURN_FALSE_IF_NOT_INIT(); DisplayPlane::reset(); // invalidate active TTM buffers if (mActiveTTMBuffers.size() > 0) { invalidateActiveTTMBuffers(); } // reset back buffers for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) { resetBackBuffer(i); } 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 OverlayPlaneBase::disable() { RETURN_FALSE_IF_NOT_INIT(); for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) { OverlayBackBufferBlk *backBuffer = mBackBuffer[i]->buf; if (!backBuffer) return false; if (!(backBuffer->OCMD & 0x1)) return true; backBuffer->OCMD &= ~0x1; } // flush flush(PLANE_DISABLE); return true; }
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::blank(int disp, int blank) { RETURN_FALSE_IF_NOT_INIT(); ALOGTRACE("disp = %d, blank = %d", disp, blank); // handle one display, lol... if (disp != 0) { ELOGTRACE("invalid disp %d", disp); // return false; } // if the device isn't created yet, create it if(!mInitialized) { initialize(); } // blank the device... //return device->blank(blank ? true : false); return true; }
bool Hwcomposer::getDisplayConfigs(int disp, uint32_t *configs, size_t *numConfigs) { RETURN_FALSE_IF_NOT_INIT(); 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 %d found", disp); return false; } return device->getDisplayConfigs(configs, numConfigs); }
bool Hwcomposer::getDisplayAttributes(int disp, uint32_t config, const uint32_t *attributes, int32_t *values) { RETURN_FALSE_IF_NOT_INIT(); 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->getDisplayAttributes(config, attributes, values); }
bool Hwcomposer::compositionComplete(int disp) { RETURN_FALSE_IF_NOT_INIT(); if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { ELOGTRACE("invalid disp %d", disp); return false; } mDisplayContext->compositionComplete(); if (disp >= (int) mDisplayDevices.size()) { return false; } IDisplayDevice *device = mDisplayDevices.itemAt(disp); if (!device) { ELOGTRACE("no device found"); return false; } return device->compositionComplete(); }
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; }
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 TngDisplayContext::commitContents(hwc_display_contents_1_t *display, HwcLayerList *layerList) { bool ret; RETURN_FALSE_IF_NOT_INIT(); if (!display || !layerList) { ELOGTRACE("invalid parameters"); return false; } IMG_hwc_layer_t *imgLayerList = (IMG_hwc_layer_t*)mImgLayers; for (size_t i = 0; i < display->numHwLayers; i++) { if (mCount >= MAXIMUM_LAYER_NUMBER) { ELOGTRACE("layer count exceeds the limit"); return false; } // check layer parameters if (!display->hwLayers[i].handle) { continue; } DisplayPlane* plane = layerList->getPlane(i); if (!plane) { continue; } ret = plane->flip(NULL); if (ret == false) { VLOGTRACE("failed to flip plane %d", i); continue; } IMG_hwc_layer_t *imgLayer = &imgLayerList[mCount++]; // update IMG layer imgLayer->psLayer = &display->hwLayers[i]; imgLayer->custom = (uint32_t)plane->getContext(); struct intel_dc_plane_ctx *ctx = (struct intel_dc_plane_ctx *)imgLayer->custom; // update z order Hwcomposer& hwc = Hwcomposer::getInstance(); DisplayPlaneManager *pm = hwc.getPlaneManager(); void *config = pm->getZOrderConfig(); if (config) { memcpy(&ctx->zorder, config, sizeof(ctx->zorder)); } else { memset(&ctx->zorder, 0, sizeof(ctx->zorder)); } VLOGTRACE("count %d, handle %#x, trans %#x, blending %#x" " sourceCrop %f,%f - %fx%f, dst %d,%d - %dx%d, custom %#x", mCount, (uint32_t)imgLayer->psLayer->handle, imgLayer->psLayer->transform, imgLayer->psLayer->blending, imgLayer->psLayer->sourceCropf.left, imgLayer->psLayer->sourceCropf.top, imgLayer->psLayer->sourceCropf.right - imgLayer->psLayer->sourceCropf.left, imgLayer->psLayer->sourceCropf.bottom - imgLayer->psLayer->sourceCropf.top, imgLayer->psLayer->displayFrame.left, imgLayer->psLayer->displayFrame.top, imgLayer->psLayer->displayFrame.right - imgLayer->psLayer->displayFrame.left, imgLayer->psLayer->displayFrame.bottom - imgLayer->psLayer->displayFrame.top, imgLayer->custom); } layerList->postFlip(); return true; }