/* * Copyright (C) 2011-2012 Team XBMC * http://www.xbmc.org * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This Program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with XBMC; see the file COPYING. If not, see * . * */ #if defined(TARGET_HYBRIS) #include #include #include #endif #include "system.h" #include #include "EGLNativeTypeHybris.h" #include "utils/log.h" #include "guilib/gui3d.h" #include "utils/StringUtils.h" HWComposer::HWComposer(unsigned int width, unsigned int height, unsigned int format, hwc_composer_device_1_t *device, hwc_display_contents_1_t **mList, hwc_layer_1_t *layer) : HWComposerNativeWindow(width, height, format) { fblayer = layer; hwcdevice = device; mlist = mList; } void HWComposer::present(HWComposerNativeWindowBuffer *buffer) { int oldretire = mlist[0]->retireFenceFd; mlist[0]->retireFenceFd = -1; fblayer->handle = buffer->handle; fblayer->acquireFenceFd = getFenceBufferFd(buffer); fblayer->releaseFenceFd = -1; int err = hwcdevice->prepare(hwcdevice, HWC_NUM_DISPLAY_TYPES, mlist); assert(err == 0); err = hwcdevice->set(hwcdevice, HWC_NUM_DISPLAY_TYPES, mlist); assert(err == 0); setFenceBufferFd(buffer, fblayer->releaseFenceFd); if (oldretire != -1) { sync_wait(oldretire, -1); close(oldretire); } } CEGLNativeTypeHybris::CEGLNativeTypeHybris() #if defined(TARGET_HYBRIS) : m_hwcModule(NULL), m_bufferList(NULL), m_hwcDevicePtr(NULL) { m_nativeWindow = NULL; m_hwNativeWindow = NULL; m_swNativeWindow = NULL; } #else { } #endif CEGLNativeTypeHybris::~CEGLNativeTypeHybris() { } bool CEGLNativeTypeHybris::CheckCompatibility() { #if defined(TARGET_HYBRIS) if(hw_get_module(HWC_HARDWARE_MODULE_ID, (const hw_module_t **) &m_hwcModule)) { return false; } if(hwc_open_1(m_hwcModule, &m_hwcDevicePtr)) { return false; } m_hwcDevicePtr->blank(m_hwcDevicePtr, 0, 0); return true; #else return false; #endif } void CEGLNativeTypeHybris::Initialize() { } void CEGLNativeTypeHybris::Destroy() { return; } bool CEGLNativeTypeHybris::CreateNativeDisplay() { m_nativeDisplay = EGL_DEFAULT_DISPLAY; return true; } bool CEGLNativeTypeHybris::CreateNativeWindow() { #if defined(TARGET_HYBRIS) RESOLUTION_INFO res; if (!GetNativeResolution(&res)) return false; size_t size = sizeof(hwc_display_contents_1_t) + 2 * sizeof(hwc_layer_1_t); hwc_display_contents_1_t *list = (hwc_display_contents_1_t *) malloc(size); m_bufferList = (hwc_display_contents_1_t **) malloc(HWC_NUM_DISPLAY_TYPES * sizeof(hwc_display_contents_1_t *)); const hwc_rect_t r = { 0, 0, res.iWidth, res.iHeight }; for (int counter = 0; counter < HWC_NUM_DISPLAY_TYPES; counter++) m_bufferList[counter] = list; hwc_layer_1_t *layer; layer = &list->hwLayers[0]; memset(layer, 0, sizeof(hwc_layer_1_t)); layer->compositionType = HWC_FRAMEBUFFER; layer->hints = 0; layer->flags = 0; layer->handle = 0; layer->transform = 0; layer->blending = HWC_BLENDING_NONE; layer->sourceCrop = r; layer->displayFrame = r; layer->visibleRegionScreen.numRects = 1; layer->visibleRegionScreen.rects = &layer->displayFrame; layer->acquireFenceFd = -1; layer->releaseFenceFd = -1; layer = &list->hwLayers[1]; memset(layer, 0, sizeof(hwc_layer_1_t)); layer->compositionType = HWC_FRAMEBUFFER_TARGET; layer->hints = 0; layer->flags = 0; layer->handle = 0; layer->transform = 0; layer->blending = HWC_BLENDING_NONE; layer->sourceCrop = r; layer->displayFrame = r; layer->visibleRegionScreen.numRects = 1; layer->visibleRegionScreen.rects = &layer->displayFrame; layer->acquireFenceFd = -1; layer->releaseFenceFd = -1; list->retireFenceFd = -1; list->flags = HWC_GEOMETRY_CHANGED; list->numHwLayers = 2; m_hwNativeWindow = new HWComposer(res.iWidth, res.iHeight, HAL_PIXEL_FORMAT_RGBA_8888, m_hwcDevicePtr, m_bufferList, &list->hwLayers[1]); if (m_hwNativeWindow == NULL) { CLog::Log(LOGERROR, "HWComposer native window failed!"); return false; } m_swNativeWindow = (static_cast (m_hwNativeWindow)); return true; #else return false; #endif } bool CEGLNativeTypeHybris::GetNativeDisplay(XBNativeDisplayType **nativeDisplay) const { if (!nativeDisplay) return false; *nativeDisplay = (XBNativeDisplayType*) &m_nativeDisplay; return true; } bool CEGLNativeTypeHybris::GetNativeWindow(XBNativeWindowType **nativeWindow) const { if (!nativeWindow) return false; #if defined(TARGET_HYBRIS) *nativeWindow = (XBNativeWindowType*) &m_swNativeWindow; return (m_swNativeWindow != NULL); #else return false; #endif } bool CEGLNativeTypeHybris::DestroyNativeDisplay() { return true; } bool CEGLNativeTypeHybris::DestroyNativeWindow() { m_nativeWindow = NULL; return true; } bool CEGLNativeTypeHybris::GetNativeResolution(RESOLUTION_INFO *res) const { #if defined(TARGET_HYBRIS) uint32_t configs[5]; size_t numConfigs = 5; int err = m_hwcDevicePtr->getDisplayConfigs(m_hwcDevicePtr, 0, configs, &numConfigs); if (err) { CLog::Log(LOGERROR, "getDisplayConfigs failed!"); return false; } int32_t attr_values[3]; uint32_t attributes[] = { HWC_DISPLAY_WIDTH, HWC_DISPLAY_HEIGHT, HWC_DISPLAY_VSYNC_PERIOD, HWC_DISPLAY_NO_ATTRIBUTE }; m_hwcDevicePtr->getDisplayAttributes(m_hwcDevicePtr, 0, configs[0], attributes, attr_values); res->iWidth = attr_values[0]; res->iHeight = attr_values[1]; res->fRefreshRate = 1000000000 / attr_values[2]; res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; res->iScreen = 0; res->bFullScreen = true; res->iSubtitles = (int)(0.965 * res->iHeight); res->fPixelRatio = 1.0f; res->iScreenWidth = res->iWidth; res->iScreenHeight = res->iHeight; res->strMode = StringUtils::Format("%dx%d @ %.2f%s - Full Screen", res->iScreenWidth, res->iScreenHeight, res->fRefreshRate, res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : ""); CLog::Log(LOGNOTICE,"Current resolution: %s\n",res->strMode.c_str()); return true; #endif } bool CEGLNativeTypeHybris::SetNativeResolution(const RESOLUTION_INFO &res) { return false; } bool CEGLNativeTypeHybris::ProbeResolutions(std::vector &resolutions) { RESOLUTION_INFO res; if (GetNativeResolution(&res) && res.iWidth > 1 && res.iHeight > 1) { resolutions.push_back(res); return true; } return false; } bool CEGLNativeTypeHybris::GetPreferredResolution(RESOLUTION_INFO *res) const { if (GetNativeResolution(res)) return true; return false; } bool CEGLNativeTypeHybris::ShowWindow(bool show) { return true; }