HWComposer.cpp revision 4e3e30c2d5a2a6f7dc4ee8696b1ac2a52dffd5dc
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2010 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 17e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#define ATRACE_TAG ATRACE_TAG_GRAPHICS 18e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 19a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <inttypes.h> 20a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <math.h> 210abc72ebe356c32354b575c48189965a0edc7890Jeff Hao#include <stdint.h> 22761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include <stdio.h> 23e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include <stdlib.h> 2462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include <string.h> 25a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <sys/types.h> 264f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers 27725a957985171d712d5c048cc3d00ff14968784bjeffhao#include <utils/Errors.h> 28ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include <utils/misc.h> 294f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include <utils/NativeHandle.h> 302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <utils/String8.h> 312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <utils/Thread.h> 324f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include <utils/Trace.h> 33a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <utils/Vector.h> 34a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 3500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include <ui/GraphicBuffer.h> 360abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 37e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include <hardware/hardware.h> 3857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers#include <hardware/hwcomposer.h> 39166db04e259ca51838c311891598664deeed85adIan Rogers 40166db04e259ca51838c311891598664deeed85adIan Rogers#include <android/configuration.h> 41166db04e259ca51838c311891598664deeed85adIan Rogers 422692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao#include <cutils/log.h> 432692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao#include <cutils/properties.h> 442692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 45e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes#include "HWComposer.h" 46e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes 47e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes#include "../Layer.h" // needed only for debugging 48e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes#include "../SurfaceFlinger.h" 49e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes 50e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughesnamespace android { 51e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes 52e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes#define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION 53e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes 54e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughesstatic uint32_t hwcApiVersion(const hwc_composer_device_1_t* hwc) { 55e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes uint32_t hwcVersion = hwc->common.version; 56e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes return hwcVersion & HARDWARE_API_VERSION_2_MAJ_MIN_MASK; 57e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes} 58e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes 59e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughesstatic uint32_t hwcHeaderVersion(const hwc_composer_device_1_t* hwc) { 60e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes uint32_t hwcVersion = hwc->common.version; 61e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes return hwcVersion & HARDWARE_API_VERSION_2_HEADER_MASK; 62e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes} 63e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes 64e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughesstatic bool hwcHasApiVersion(const hwc_composer_device_1_t* hwc, 65e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes uint32_t version) { 66e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes return hwcApiVersion(hwc) >= (version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK); 67e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes} 68e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes 69e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes// --------------------------------------------------------------------------- 70e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes 71e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughesstruct HWComposer::cb_context { 72e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes struct callbacks : public hwc_procs_t { 73e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes // these are here to facilitate the transition when adding 74e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes // new callbacks (an implementation can check for NULL before 75e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes // calling a new callback). 76e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes void (*zero[4])(void); 77e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes }; 78e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes callbacks procs; 7962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers HWComposer* hwc; 807934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom}; 817934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom 827934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom// --------------------------------------------------------------------------- 8362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 847934ac288acfb2552bb0b06ec1f61e5820d924a4Brian CarlstromHWComposer::HWComposer( 8562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const sp<SurfaceFlinger>& flinger, 8662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers EventHandler& handler) 870abc72ebe356c32354b575c48189965a0edc7890Jeff Hao : mFlinger(flinger), 880abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mFbDev(0), mHwc(0), mNumDisplays(1), 890abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mCBContext(new cb_context), 905ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao mEventHandler(handler), 910abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mDebugForceFakeVSync(false) 920abc72ebe356c32354b575c48189965a0edc7890Jeff Hao{ 93e2f77e7592842cad5a59e73535b8982c35e156caIan Rogers for (size_t i =0 ; i<MAX_HWC_DISPLAYS ; i++) { 940abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mLists[i] = 0; 950abc72ebe356c32354b575c48189965a0edc7890Jeff Hao } 960abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 970abc72ebe356c32354b575c48189965a0edc7890Jeff Hao for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) { 980abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mLastHwVSync[i] = 0; 990abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mVSyncCounts[i] = 0; 1000abc72ebe356c32354b575c48189965a0edc7890Jeff Hao } 1010abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 102e2f77e7592842cad5a59e73535b8982c35e156caIan Rogers char value[PROPERTY_VALUE_MAX]; 1030abc72ebe356c32354b575c48189965a0edc7890Jeff Hao property_get("debug.sf.no_hw_vsync", value, "0"); 1040abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mDebugForceFakeVSync = atoi(value); 1050abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 1060abc72ebe356c32354b575c48189965a0edc7890Jeff Hao bool needVSyncThread = true; 107e2f77e7592842cad5a59e73535b8982c35e156caIan Rogers 1080abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // Note: some devices may insist that the FB HAL be opened before HWC. 1090abc72ebe356c32354b575c48189965a0edc7890Jeff Hao int fberr = loadFbHalModule(); 110a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao loadHwcModule(); 111a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 112a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { 113a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // close FB HAL if we don't needed it. 114a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // FIXME: this is temporary until we're not forced to open FB HAL 1157934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom // before HWC. 1167934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom framebuffer_close(mFbDev); 117a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao mFbDev = NULL; 11862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 11962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 12062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory. 12162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if ((!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) 12262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers && !mFbDev) { 12362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ALOGE("ERROR: failed to open framebuffer (%s), aborting", 1240abc72ebe356c32354b575c48189965a0edc7890Jeff Hao strerror(-fberr)); 1250abc72ebe356c32354b575c48189965a0edc7890Jeff Hao abort(); 1265ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao } 127e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes 128ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom // these display IDs are always reserved 129ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom for (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i++) { 130a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao mAllocatedDisplayIDs.markBit(i); 131e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes } 13262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 13362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (mHwc) { 134a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER, 135a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao (hwcApiVersion(mHwc) >> 24) & 0xff, 136ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom (hwcApiVersion(mHwc) >> 16) & 0xff); 13762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (mHwc->registerProcs) { 13862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mCBContext->hwc = this; 13962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mCBContext->procs.invalidate = &hook_invalidate; 14062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mCBContext->procs.vsync = &hook_vsync; 141e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) 142e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes mCBContext->procs.hotplug = &hook_hotplug; 1435ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao else 1445ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao mCBContext->procs.hotplug = NULL; 1455ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero)); 1465ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao mHwc->registerProcs(mHwc, &mCBContext->procs); 1475ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao } 1485ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 1495ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // don't need a vsync thread if we have a hardware composer 1505ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao needVSyncThread = false; 1515ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // always turn vsync off when we start 1525ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); 1535ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 1545ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // the number of displays we actually have depends on the 1555ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // hw composer version 15662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) { 157e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes // 1.3 adds support for virtual displays 15862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mNumDisplays = MAX_HWC_DISPLAYS; 159e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { 16062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // 1.1 adds support for multiple displays 1615ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao mNumDisplays = NUM_BUILTIN_DISPLAYS; 16262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 163e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes mNumDisplays = 1; 164a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao } 165a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao } 16662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 16762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (mFbDev) { 16862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)), 16962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "should only have fbdev if no hwc or hwc is 1.0"); 17062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 17162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]); 17262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.connected = true; 17362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.format = mFbDev->format; 17462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers DisplayConfig config = DisplayConfig(); 17562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers config.width = mFbDev->width; 17662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers config.height = mFbDev->height; 17762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers config.xdpi = mFbDev->xdpi; 17862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers config.ydpi = mFbDev->ydpi; 17962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers config.refresh = nsecs_t(1e9 / mFbDev->fps); 18062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.configs.push_back(config); 181e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes disp.currentConfig = 0; 18262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else if (mHwc) { 18362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // here we're guaranteed to have at least HWC 1.1 184a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) { 185a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao queryDisplayProperties(i); 186e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes } 187e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes } 18857dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao 189a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao if (needVSyncThread) { 190e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes // we don't have VSYNC support, we need to fake it 191a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao mVSyncThread = new VSyncThread(*this); 192a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao } 193a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao} 194a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 1955ce4b178d2483df679e7f718e379305e5d42a300Jeff HaoHWComposer::~HWComposer() { 1965ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao if (mHwc) { 19757dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); 19857dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao } 199a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao if (mVSyncThread != NULL) { 200a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao mVSyncThread->requestExitAndWait(); 201e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes } 202e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes if (mHwc) { 203e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes hwc_close_1(mHwc); 204e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes } 205e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes if (mFbDev) { 206e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes framebuffer_close(mFbDev); 207e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes } 208e119a3623ffbd55ff856d4eaac4dc4ef0c90a089Elliott Hughes delete mCBContext; 209a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao} 210a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 2115ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao// Load and prepare the hardware composer module. Sets mHwc. 2125ce4b178d2483df679e7f718e379305e5d42a300Jeff Haovoid HWComposer::loadHwcModule() 213a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao{ 214a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao hw_module_t const* module; 215ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes 216ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) { 2175ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao ALOGE("%s module not found", HWC_HARDWARE_MODULE_ID); 2185ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao return; 219a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao } 220a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 221ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes int err = hwc_open_1(module, &mHwc); 222ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes if (err) { 2235ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao ALOGE("%s device failed to initialize (%s)", 2245ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao HWC_HARDWARE_COMPOSER, strerror(-err)); 2255ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao return; 2265ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao } 227a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 228a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) || 229ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes hwcHeaderVersion(mHwc) < MIN_HWC_HEADER_VERSION || 230ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION) { 2315ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao ALOGE("%s device version %#x unsupported, will not be used", 2325ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao HWC_HARDWARE_COMPOSER, mHwc->common.version); 2335ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao hwc_close_1(mHwc); 2345ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao mHwc = NULL; 2355ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao return; 2365ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao } 2375ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao} 2385ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 239a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao// Load and prepare the FB HAL, which uses the gralloc module. Sets mFbDev. 240a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhaoint HWComposer::loadFbHalModule() 2410abc72ebe356c32354b575c48189965a0edc7890Jeff Hao{ 2420abc72ebe356c32354b575c48189965a0edc7890Jeff Hao hw_module_t const* module; 2430abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 244e2f77e7592842cad5a59e73535b8982c35e156caIan Rogers int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); 2450abc72ebe356c32354b575c48189965a0edc7890Jeff Hao if (err != 0) { 2460abc72ebe356c32354b575c48189965a0edc7890Jeff Hao ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID); 2470abc72ebe356c32354b575c48189965a0edc7890Jeff Hao return err; 2480abc72ebe356c32354b575c48189965a0edc7890Jeff Hao } 2495ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 2505ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao return framebuffer_open(module, &mFbDev); 2515ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao} 2525ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 2535ce4b178d2483df679e7f718e379305e5d42a300Jeff Haostatus_t HWComposer::initCheck() const { 2545ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao return mHwc ? NO_ERROR : NO_INIT; 2555ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao} 2560abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 257e2f77e7592842cad5a59e73535b8982c35e156caIan Rogersvoid HWComposer::hook_invalidate(const struct hwc_procs* procs) { 2580abc72ebe356c32354b575c48189965a0edc7890Jeff Hao cb_context* ctx = reinterpret_cast<cb_context*>( 2595ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao const_cast<hwc_procs_t*>(procs)); 2605ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao ctx->hwc->invalidate(); 2615ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao} 262c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao 263c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Haovoid HWComposer::hook_vsync(const struct hwc_procs* procs, int disp, 264c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao int64_t timestamp) { 265c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao cb_context* ctx = reinterpret_cast<cb_context*>( 2665ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao const_cast<hwc_procs_t*>(procs)); 2675ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao ctx->hwc->vsync(disp, timestamp); 2680abc72ebe356c32354b575c48189965a0edc7890Jeff Hao} 269e2f77e7592842cad5a59e73535b8982c35e156caIan Rogers 2700abc72ebe356c32354b575c48189965a0edc7890Jeff Haovoid HWComposer::hook_hotplug(const struct hwc_procs* procs, int disp, 271c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao int connected) { 272c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao cb_context* ctx = reinterpret_cast<cb_context*>( 2730abc72ebe356c32354b575c48189965a0edc7890Jeff Hao const_cast<hwc_procs_t*>(procs)); 2740abc72ebe356c32354b575c48189965a0edc7890Jeff Hao ctx->hwc->hotplug(disp, connected); 2750abc72ebe356c32354b575c48189965a0edc7890Jeff Hao} 2760abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 277e2f77e7592842cad5a59e73535b8982c35e156caIan Rogersvoid HWComposer::invalidate() { 278e2f77e7592842cad5a59e73535b8982c35e156caIan Rogers mFlinger->repaintEverything(); 2790abc72ebe356c32354b575c48189965a0edc7890Jeff Hao} 2800abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 2810abc72ebe356c32354b575c48189965a0edc7890Jeff Haovoid HWComposer::vsync(int disp, int64_t timestamp) { 2820abc72ebe356c32354b575c48189965a0edc7890Jeff Hao if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) { 2830abc72ebe356c32354b575c48189965a0edc7890Jeff Hao { 2840abc72ebe356c32354b575c48189965a0edc7890Jeff Hao Mutex::Autolock _l(mLock); 285e2f77e7592842cad5a59e73535b8982c35e156caIan Rogers 2860abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // There have been reports of HWCs that signal several vsync events 287c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao // with the same timestamp when turning the display off and on. This 288c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao // is a bug in the HWC implementation, but filter the extra events 2890abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // out here so they don't cause havoc downstream. 2900abc72ebe356c32354b575c48189965a0edc7890Jeff Hao if (timestamp == mLastHwVSync[disp]) { 2910abc72ebe356c32354b575c48189965a0edc7890Jeff Hao ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")", 292c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao timestamp); 293c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao return; 2940abc72ebe356c32354b575c48189965a0edc7890Jeff Hao } 2955ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 2960abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mLastHwVSync[disp] = timestamp; 2970abc72ebe356c32354b575c48189965a0edc7890Jeff Hao } 2980abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 2990abc72ebe356c32354b575c48189965a0edc7890Jeff Hao char tag[16]; 3000abc72ebe356c32354b575c48189965a0edc7890Jeff Hao snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp); 30123009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao ATRACE_INT(tag, ++mVSyncCounts[disp] & 1); 3020abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 3030abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mEventHandler.onVSyncReceived(disp, timestamp); 3040abc72ebe356c32354b575c48189965a0edc7890Jeff Hao } 3050abc72ebe356c32354b575c48189965a0edc7890Jeff Hao} 30623009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao 3075ce4b178d2483df679e7f718e379305e5d42a300Jeff Haovoid HWComposer::hotplug(int disp, int connected) { 3080abc72ebe356c32354b575c48189965a0edc7890Jeff Hao if (disp == HWC_DISPLAY_PRIMARY || disp >= VIRTUAL_DISPLAY_ID_BASE) { 3090abc72ebe356c32354b575c48189965a0edc7890Jeff Hao ALOGE("hotplug event received for invalid display: disp=%d connected=%d", 3100abc72ebe356c32354b575c48189965a0edc7890Jeff Hao disp, connected); 3110abc72ebe356c32354b575c48189965a0edc7890Jeff Hao return; 3120abc72ebe356c32354b575c48189965a0edc7890Jeff Hao } 3130abc72ebe356c32354b575c48189965a0edc7890Jeff Hao queryDisplayProperties(disp); 3140abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mEventHandler.onHotplugReceived(disp, bool(connected)); 3150abc72ebe356c32354b575c48189965a0edc7890Jeff Hao} 3160abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 3170abc72ebe356c32354b575c48189965a0edc7890Jeff Haostatic float getDefaultDensity(uint32_t width, uint32_t height) { 3180abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // Default density is based on TVs: 1080p displays get XHIGH density, 3190abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // lower-resolution displays get TV density. Maybe eventually we'll need 3200abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // to update it for 4K displays, though hopefully those just report 3210abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // accurate DPI information to begin with. This is also used for virtual 3220abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // displays and even primary displays with older hwcomposers, so be 3230abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // careful about orientation. 3245ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 3250abc72ebe356c32354b575c48189965a0edc7890Jeff Hao uint32_t h = width < height ? width : height; 3260abc72ebe356c32354b575c48189965a0edc7890Jeff Hao if (h >= 1080) return ACONFIGURATION_DENSITY_XHIGH; 3270abc72ebe356c32354b575c48189965a0edc7890Jeff Hao else return ACONFIGURATION_DENSITY_TV; 3280abc72ebe356c32354b575c48189965a0edc7890Jeff Hao} 3290abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 3300abc72ebe356c32354b575c48189965a0edc7890Jeff Haostatic const uint32_t DISPLAY_ATTRIBUTES[] = { 33162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers HWC_DISPLAY_VSYNC_PERIOD, 33223009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao HWC_DISPLAY_WIDTH, 33362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers HWC_DISPLAY_HEIGHT, 33462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers HWC_DISPLAY_DPI_X, 33562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers HWC_DISPLAY_DPI_Y, 33662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers HWC_DISPLAY_NO_ATTRIBUTE, 33762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers}; 33862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#define NUM_DISPLAY_ATTRIBUTES (sizeof(DISPLAY_ATTRIBUTES) / sizeof(DISPLAY_ATTRIBUTES)[0]) 33962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 340e343b76af81a005ef64f5e75a555389fd9147dabjeffhaostatus_t HWComposer::queryDisplayProperties(int disp) { 34162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 34262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers LOG_ALWAYS_FATAL_IF(!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)); 343a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 3442692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // use zero as default value for unspecified attributes 34562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers int32_t values[NUM_DISPLAY_ATTRIBUTES - 1]; 346a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao memset(values, 0, sizeof(values)); 347a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 3487571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom const size_t MAX_NUM_CONFIGS = 128; 349a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao uint32_t configs[MAX_NUM_CONFIGS] = {0}; 35062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers size_t numConfigs = MAX_NUM_CONFIGS; 351761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes status_t err = mHwc->getDisplayConfigs(mHwc, disp, configs, &numConfigs); 352a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao if (err != NO_ERROR) { 35362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // this can happen if an unpluggable display is not connected 354b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao mDisplayData[disp].connected = false; 35562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return err; 35662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 35762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 358a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao mDisplayData[disp].currentConfig = 0; 359a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao for (size_t c = 0; c < numConfigs; ++c) { 360a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao err = mHwc->getDisplayAttributes(mHwc, disp, configs[c], 361a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao DISPLAY_ATTRIBUTES, values); 3622692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao if (err != NO_ERROR) { 36362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // we can't get this display's info. turn it off. 36462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mDisplayData[disp].connected = false; 365df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom return err; 36662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 36762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 36823009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao DisplayConfig config = DisplayConfig(); 3690791adc2249366c50684935a4c42ba5e58bc3746jeffhao for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) { 37062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers switch (DISPLAY_ATTRIBUTES[i]) { 37162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers case HWC_DISPLAY_VSYNC_PERIOD: 37262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers config.refresh = nsecs_t(values[i]); 37362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 3742692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao case HWC_DISPLAY_WIDTH: 37523009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao config.width = values[i]; 37623009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao break; 37723009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao case HWC_DISPLAY_HEIGHT: 37823009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao config.height = values[i]; 37923009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao break; 38023009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao case HWC_DISPLAY_DPI_X: 3810abc72ebe356c32354b575c48189965a0edc7890Jeff Hao config.xdpi = values[i] / 1000.0f; 3820abc72ebe356c32354b575c48189965a0edc7890Jeff Hao break; 3830abc72ebe356c32354b575c48189965a0edc7890Jeff Hao case HWC_DISPLAY_DPI_Y: 3840abc72ebe356c32354b575c48189965a0edc7890Jeff Hao config.ydpi = values[i] / 1000.0f; 3850abc72ebe356c32354b575c48189965a0edc7890Jeff Hao break; 3860abc72ebe356c32354b575c48189965a0edc7890Jeff Hao default: 38762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ALOG_ASSERT(false, "unknown display attribute[%zu] %#x", 38862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers i, DISPLAY_ATTRIBUTES[i]); 38962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 3902692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao } 3912692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao } 3922692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 39362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (config.xdpi == 0.0f || config.ydpi == 0.0f) { 39462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers float dpi = getDefaultDensity(config.width, config.height); 39562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers config.xdpi = dpi; 3960abc72ebe356c32354b575c48189965a0edc7890Jeff Hao config.ydpi = dpi; 39762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 39862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 39962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mDisplayData[disp].configs.push_back(config); 40062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 40162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 40262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // FIXME: what should we set the format to? 40362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888; 4040abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mDisplayData[disp].connected = true; 4050abc72ebe356c32354b575c48189965a0edc7890Jeff Hao return NO_ERROR; 40662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 4072692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 40862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatus_t HWComposer::setVirtualDisplayProperties(int32_t id, 40962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers uint32_t w, uint32_t h, uint32_t format) { 4100abc72ebe356c32354b575c48189965a0edc7890Jeff Hao if (id < VIRTUAL_DISPLAY_ID_BASE || id >= int32_t(mNumDisplays) || 41123009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao !mAllocatedDisplayIDs.hasBit(id)) { 4125ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao return BAD_INDEX; 4135ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao } 4145ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao size_t configId = mDisplayData[id].currentConfig; 4150abc72ebe356c32354b575c48189965a0edc7890Jeff Hao mDisplayData[id].format = format; 4160abc72ebe356c32354b575c48189965a0edc7890Jeff Hao DisplayConfig& config = mDisplayData[id].configs.editItemAt(configId); 4170abc72ebe356c32354b575c48189965a0edc7890Jeff Hao config.width = w; 4180abc72ebe356c32354b575c48189965a0edc7890Jeff Hao config.height = h; 4190abc72ebe356c32354b575c48189965a0edc7890Jeff Hao config.xdpi = config.ydpi = getDefaultDensity(w, h); 42062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return NO_ERROR; 42162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 42262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 4230abc72ebe356c32354b575c48189965a0edc7890Jeff Haoint32_t HWComposer::allocateDisplayId() { 42423009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao if (mAllocatedDisplayIDs.count() >= mNumDisplays) { 4250abc72ebe356c32354b575c48189965a0edc7890Jeff Hao return NO_MEMORY; 4260abc72ebe356c32354b575c48189965a0edc7890Jeff Hao } 4272692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao int32_t id = mAllocatedDisplayIDs.firstUnmarkedBit(); 4282692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao mAllocatedDisplayIDs.markBit(id); 429b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao mDisplayData[id].connected = true; 43064caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao mDisplayData[id].configs.resize(1); 43162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mDisplayData[id].currentConfig = 0; 432b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao return id; 433b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao} 434b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao 43564caa7dcf46ed6139b766dbe77fbd7353899417fJeff Haostatus_t HWComposer::freeDisplayId(int32_t id) { 43662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (id < NUM_BUILTIN_DISPLAYS) { 43764caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao // cannot free the reserved IDs 43864caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao return BAD_VALUE; 43964caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao } 44064caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) { 44164caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao return BAD_INDEX; 44264caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao } 44364caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao mAllocatedDisplayIDs.clearBit(id); 44462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mDisplayData[id].connected = false; 445a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao return NO_ERROR; 44623009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao} 44762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 44823009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Haonsecs_t HWComposer::getRefreshTimestamp(int disp) const { 44923009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao // this returns the last refresh timestamp. 450a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // if the last one is not available, we estimate it based on 45162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // the refresh period and whatever closest timestamp we have. 4522692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao Mutex::Autolock _l(mLock); 4532692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao nsecs_t now = systemTime(CLOCK_MONOTONIC); 45462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers size_t configId = mDisplayData[disp].currentConfig; 4552692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao return now - ((now - mLastHwVSync[disp]) % 4562692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao mDisplayData[disp].configs[configId].refresh); 45762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 45862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 45962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogerssp<Fence> HWComposer::getDisplayFence(int disp) const { 460a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao return mDisplayData[disp].lastDisplayFence; 461a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao} 4622692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 4632692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhaouint32_t HWComposer::getFormat(int disp) const { 46462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (static_cast<uint32_t>(disp) >= MAX_HWC_DISPLAYS || !mAllocatedDisplayIDs.hasBit(disp)) { 46562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return HAL_PIXEL_FORMAT_RGBA_8888; 46662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 46762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return mDisplayData[disp].format; 46862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 46962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 470a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 47162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersbool HWComposer::isConnected(int disp) const { 47262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return mDisplayData[disp].connected; 473ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom} 47462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 47562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersuint32_t HWComposer::getWidth(int disp) const { 47662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers size_t currentConfig = mDisplayData[disp].currentConfig; 47762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return mDisplayData[disp].configs[currentConfig].width; 478e343b76af81a005ef64f5e75a555389fd9147dabjeffhao} 479e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 4802692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhaouint32_t HWComposer::getHeight(int disp) const { 481a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao size_t currentConfig = mDisplayData[disp].currentConfig; 482a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao return mDisplayData[disp].configs[currentConfig].height; 483a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao} 484a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 4855ce4b178d2483df679e7f718e379305e5d42a300Jeff Haofloat HWComposer::getDpiX(int disp) const { 486a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao size_t currentConfig = mDisplayData[disp].currentConfig; 4870791adc2249366c50684935a4c42ba5e58bc3746jeffhao return mDisplayData[disp].configs[currentConfig].xdpi; 4880791adc2249366c50684935a4c42ba5e58bc3746jeffhao} 4890791adc2249366c50684935a4c42ba5e58bc3746jeffhao 4900791adc2249366c50684935a4c42ba5e58bc3746jeffhaofloat HWComposer::getDpiY(int disp) const { 491ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom size_t currentConfig = mDisplayData[disp].currentConfig; 49262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return mDisplayData[disp].configs[currentConfig].ydpi; 493a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao} 494a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 495a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhaonsecs_t HWComposer::getRefreshPeriod(int disp) const { 496a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao size_t currentConfig = mDisplayData[disp].currentConfig; 49762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return mDisplayData[disp].configs[currentConfig].refresh; 498a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao} 499a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 500a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhaoconst Vector<HWComposer::DisplayConfig>& HWComposer::getConfigs(int disp) const { 501a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao return mDisplayData[disp].configs; 502a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao} 503a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 504a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhaosize_t HWComposer::getCurrentConfig(int disp) const { 505a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao return mDisplayData[disp].currentConfig; 506a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao} 507a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 508a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhaovoid HWComposer::eventControl(int disp, int event, int enabled) { 50962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (uint32_t(disp)>31 || !mAllocatedDisplayIDs.hasBit(disp)) { 51062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ALOGD("eventControl ignoring event %d on unallocated disp %d (en=%d)", 5115ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao event, disp, enabled); 512a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao return; 5130791adc2249366c50684935a4c42ba5e58bc3746jeffhao } 5140791adc2249366c50684935a4c42ba5e58bc3746jeffhao if (event != EVENT_VSYNC) { 5150791adc2249366c50684935a4c42ba5e58bc3746jeffhao ALOGW("eventControl got unexpected event %d (disp=%d en=%d)", 5160791adc2249366c50684935a4c42ba5e58bc3746jeffhao event, disp, enabled); 5170791adc2249366c50684935a4c42ba5e58bc3746jeffhao return; 518a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao } 519a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao status_t err = NO_ERROR; 520a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao if (mHwc && !mDebugForceFakeVSync) { 52162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // NOTE: we use our own internal lock here because we have to call 522a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // into the HWC with the lock held, and we want to make sure 523a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // that even if HWC blocks (which it shouldn't), it won't 524a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // affect other threads. 5252692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao Mutex::Autolock _l(mEventControlLock); 5267b9d996e4cd7d154bb1a244d67139aff0c363cf2Elliott Hughes const int32_t eventBit = 1UL << event; 527a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao const int32_t newValue = enabled ? eventBit : 0; 528a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao const int32_t oldValue = mDisplayData[disp].events & eventBit; 5292692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao if (newValue != oldValue) { 530a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao ATRACE_CALL(); 531a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao err = mHwc->eventControl(mHwc, disp, event, enabled); 53262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (!err) { 53362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers int32_t& events(mDisplayData[disp].events); 53462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers events = (events & ~eventBit) | newValue; 53562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 53662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers char tag[16]; 537a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", disp); 538a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao ATRACE_INT(tag, enabled); 5392692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao } 5407b9d996e4cd7d154bb1a244d67139aff0c363cf2Elliott Hughes } 5417b9d996e4cd7d154bb1a244d67139aff0c363cf2Elliott Hughes // error here should not happen -- not sure what we should 54262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // do if it does. 543a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao ALOGE_IF(err, "eventControl(%d, %d) failed %s", 544a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao event, enabled, strerror(-err)); 545e343b76af81a005ef64f5e75a555389fd9147dabjeffhao } 546e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 54762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (err == NO_ERROR && mVSyncThread != NULL) { 548ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mVSyncThread->setEnabled(enabled); 54962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 55062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 55162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 55262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatus_t HWComposer::createWorkList(int32_t id, size_t numLayers) { 55362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) { 554ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return BAD_INDEX; 555c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao } 556c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao 557c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao if (mHwc) { 558c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao DisplayData& disp(mDisplayData[id]); 559c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { 56062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // we need space for the HWC_FRAMEBUFFER_TARGET 56162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers numLayers++; 56262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 563ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom if (disp.capacity < numLayers || disp.list == NULL) { 56462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers size_t size = sizeof(hwc_display_contents_1_t) 56562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers + numLayers * sizeof(hwc_layer_1_t); 566c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao free(disp.list); 567c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.list = (hwc_display_contents_1_t*)malloc(size); 568c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.capacity = numLayers; 569c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao } 570c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { 57162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.framebufferTarget = &disp.list->hwLayers[numLayers - 1]; 57262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers memset(disp.framebufferTarget, 0, sizeof(hwc_layer_1_t)); 573ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom const DisplayConfig& currentConfig = 574c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.configs[disp.currentConfig]; 575c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao const hwc_rect_t r = { 0, 0, 576c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao (int) currentConfig.width, (int) currentConfig.height }; 577c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET; 578c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.framebufferTarget->hints = 0; 57962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.framebufferTarget->flags = 0; 58062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.framebufferTarget->handle = disp.fbTargetHandle; 58162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.framebufferTarget->transform = 0; 582ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom disp.framebufferTarget->blending = HWC_BLENDING_PREMULT; 58362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) { 58462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.framebufferTarget->sourceCropf.left = 0; 58562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.framebufferTarget->sourceCropf.top = 0; 58662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.framebufferTarget->sourceCropf.right = 587a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao currentConfig.width; 588c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.framebufferTarget->sourceCropf.bottom = 589c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao currentConfig.height; 590c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao } else { 591c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.framebufferTarget->sourceCrop = r; 592c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao } 593c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.framebufferTarget->displayFrame = r; 594c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.framebufferTarget->visibleRegionScreen.numRects = 1; 595c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.framebufferTarget->visibleRegionScreen.rects = 596c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao &disp.framebufferTarget->displayFrame; 597c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.framebufferTarget->acquireFenceFd = -1; 598c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.framebufferTarget->releaseFenceFd = -1; 599c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.framebufferTarget->planeAlpha = 0xFF; 600c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao } 601c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.list->retireFenceFd = -1; 602c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.list->flags = HWC_GEOMETRY_CHANGED; 603c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao disp.list->numHwLayers = numLayers; 604ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom } 605c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao return NO_ERROR; 606c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao} 607a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 608a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhaostatus_t HWComposer::setFramebufferTarget(int32_t id, 609a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf) { 610a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) { 611a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao return BAD_INDEX; 61262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 613a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao DisplayData& disp(mDisplayData[id]); 614a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao if (!disp.framebufferTarget) { 615a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // this should never happen, but apparently eglCreateWindowSurface() 616a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // triggers a Surface::queueBuffer() on some 617a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // devices (!?) -- log and ignore. 618a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao ALOGE("HWComposer: framebufferTarget is null"); 61962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return NO_ERROR; 62062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 62162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 62262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers int acquireFenceFd = -1; 62362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (acquireFence->isValid()) { 62462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers acquireFenceFd = acquireFence->dup(); 62562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 62662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 62762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // ALOGD("fbPost: handle=%p, fence=%d", buf->handle, acquireFenceFd); 62862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.fbTargetHandle = buf->handle; 62962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.framebufferTarget->handle = disp.fbTargetHandle; 63062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers disp.framebufferTarget->acquireFenceFd = acquireFenceFd; 63162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return NO_ERROR; 63262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 63362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 63462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatus_t HWComposer::prepare() { 635a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao for (size_t i=0 ; i<mNumDisplays ; i++) { 636a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao DisplayData& disp(mDisplayData[i]); 6372692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao if (disp.framebufferTarget) { 63862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // make sure to reset the type to HWC_FRAMEBUFFER_TARGET 639a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // DO NOT reset the handle field to NULL, because it's possible 640a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // that we have nothing to redraw (eg: eglSwapBuffers() not called) 641a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // in which case, we should continue to use the same buffer. 642a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao LOG_FATAL_IF(disp.list == NULL); 643a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET; 644a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao } 645e343b76af81a005ef64f5e75a555389fd9147dabjeffhao if (!disp.connected && disp.list != NULL) { 646a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao ALOGW("WARNING: disp %zu: connected, non-null list, layers=%zu", 647a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao i, disp.list->numHwLayers); 648a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao } 649a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao mLists[i] = disp.list; 650a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao if (mLists[i]) { 65162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) { 652ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mLists[i]->outbuf = disp.outbufHandle; 6532692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao mLists[i]->outbufAcquireFenceFd = -1; 65462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { 655a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // garbage data to catch improper use 656a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao mLists[i]->dpy = (hwc_display_t)0xDEADBEEF; 65762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mLists[i]->sur = (hwc_surface_t)0xDEADBEEF; 658ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom } else { 65962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mLists[i]->dpy = EGL_NO_DISPLAY; 66062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mLists[i]->sur = EGL_NO_SURFACE; 661a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao } 662a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao } 663a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao } 66402e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier 66562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers int err = mHwc->prepare(mHwc, mNumDisplays, mLists); 66602e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier ALOGE_IF(err, "HWComposer: prepare failed (%s)", strerror(-err)); 66762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 6680399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (err == NO_ERROR) { 669a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // here we're just making sure that "skip" layers are set 6700399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // to HWC_FRAMEBUFFER and we're also counting how many layers 671a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // we have of each type. 672a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // 673a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // If there are no window layers, we treat the display has having FB 674a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // composition, because SurfaceFlinger will use GLES to draw the 675ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes // wormhole region. 676ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes for (size_t i=0 ; i<mNumDisplays ; i++) { 677ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes DisplayData& disp(mDisplayData[i]); 678ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes disp.hasFbComp = false; 679a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao disp.hasOvComp = false; 680a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao if (disp.list) { 681a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao for (size_t i=0 ; i<disp.list->numHwLayers ; i++) { 68281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers hwc_layer_1_t& l = disp.list->hwLayers[i]; 68381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 68481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers //ALOGD("prepare: %d, type=%d, handle=%p", 685a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // i, l.compositionType, l.handle); 686a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 687a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao if (l.flags & HWC_SKIP_LAYER) { 688e343b76af81a005ef64f5e75a555389fd9147dabjeffhao l.compositionType = HWC_FRAMEBUFFER; 689 } 690 if (l.compositionType == HWC_FRAMEBUFFER) { 691 disp.hasFbComp = true; 692 } 693 if (l.compositionType == HWC_OVERLAY) { 694 disp.hasOvComp = true; 695 } 696 if (l.compositionType == HWC_CURSOR_OVERLAY) { 697 disp.hasOvComp = true; 698 } 699 } 700 if (disp.list->numHwLayers == (disp.framebufferTarget ? 1 : 0)) { 701 disp.hasFbComp = true; 702 } 703 } else { 704 disp.hasFbComp = true; 705 } 706 } 707 } 708 return (status_t)err; 709} 710 711bool HWComposer::hasHwcComposition(int32_t id) const { 712 if (!mHwc || uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) 713 return false; 714 return mDisplayData[id].hasOvComp; 715} 716 717bool HWComposer::hasGlesComposition(int32_t id) const { 718 if (!mHwc || uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) 719 return true; 720 return mDisplayData[id].hasFbComp; 721} 722 723sp<Fence> HWComposer::getAndResetReleaseFence(int32_t id) { 724 if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) 725 return Fence::NO_FENCE; 726 727 int fd = INVALID_OPERATION; 728 if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { 729 const DisplayData& disp(mDisplayData[id]); 730 if (disp.framebufferTarget) { 731 fd = disp.framebufferTarget->releaseFenceFd; 732 disp.framebufferTarget->acquireFenceFd = -1; 733 disp.framebufferTarget->releaseFenceFd = -1; 734 } 735 } 736 return fd >= 0 ? new Fence(fd) : Fence::NO_FENCE; 737} 738 739status_t HWComposer::commit() { 740 int err = NO_ERROR; 741 if (mHwc) { 742 if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { 743 // On version 1.0, the OpenGL ES target surface is communicated 744 // by the (dpy, sur) fields and we are guaranteed to have only 745 // a single display. 746 mLists[0]->dpy = eglGetCurrentDisplay(); 747 mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW); 748 } 749 750 for (size_t i=VIRTUAL_DISPLAY_ID_BASE; i<mNumDisplays; i++) { 751 DisplayData& disp(mDisplayData[i]); 752 if (disp.outbufHandle) { 753 mLists[i]->outbuf = disp.outbufHandle; 754 mLists[i]->outbufAcquireFenceFd = 755 disp.outbufAcquireFence->dup(); 756 } 757 } 758 759 err = mHwc->set(mHwc, mNumDisplays, mLists); 760 761 for (size_t i=0 ; i<mNumDisplays ; i++) { 762 DisplayData& disp(mDisplayData[i]); 763 disp.lastDisplayFence = disp.lastRetireFence; 764 disp.lastRetireFence = Fence::NO_FENCE; 765 if (disp.list) { 766 if (disp.list->retireFenceFd != -1) { 767 disp.lastRetireFence = new Fence(disp.list->retireFenceFd); 768 disp.list->retireFenceFd = -1; 769 } 770 disp.list->flags &= ~HWC_GEOMETRY_CHANGED; 771 } 772 } 773 } 774 return (status_t)err; 775} 776 777status_t HWComposer::setPowerMode(int disp, int mode) { 778 LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE); 779 if (mHwc) { 780 if (mode == HWC_POWER_MODE_OFF) { 781 eventControl(disp, HWC_EVENT_VSYNC, 0); 782 } 783 if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) { 784 return (status_t)mHwc->setPowerMode(mHwc, disp, mode); 785 } else { 786 return (status_t)mHwc->blank(mHwc, disp, 787 mode == HWC_POWER_MODE_OFF ? 1 : 0); 788 } 789 } 790 return NO_ERROR; 791} 792 793status_t HWComposer::setActiveConfig(int disp, int mode) { 794 LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE); 795 DisplayData& dd(mDisplayData[disp]); 796 dd.currentConfig = mode; 797 if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) { 798 return (status_t)mHwc->setActiveConfig(mHwc, disp, mode); 799 } else { 800 LOG_FATAL_IF(mode != 0); 801 } 802 return NO_ERROR; 803} 804 805void HWComposer::disconnectDisplay(int disp) { 806 LOG_ALWAYS_FATAL_IF(disp < 0 || disp == HWC_DISPLAY_PRIMARY); 807 DisplayData& dd(mDisplayData[disp]); 808 free(dd.list); 809 dd.list = NULL; 810 dd.framebufferTarget = NULL; // points into dd.list 811 dd.fbTargetHandle = NULL; 812 dd.outbufHandle = NULL; 813 dd.lastRetireFence = Fence::NO_FENCE; 814 dd.lastDisplayFence = Fence::NO_FENCE; 815 dd.outbufAcquireFence = Fence::NO_FENCE; 816 // clear all the previous configs and repopulate when a new 817 // device is added 818 dd.configs.clear(); 819} 820 821int HWComposer::getVisualID() const { 822 if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { 823 // FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED 824 // is supported by the implementation. we can only be in this case 825 // if we have HWC 1.1 826 return HAL_PIXEL_FORMAT_RGBA_8888; 827 //return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 828 } else { 829 return mFbDev->format; 830 } 831} 832 833bool HWComposer::supportsFramebufferTarget() const { 834 return (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)); 835} 836 837int HWComposer::fbPost(int32_t id, 838 const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) { 839 if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { 840 return setFramebufferTarget(id, acquireFence, buffer); 841 } else { 842 acquireFence->waitForever("HWComposer::fbPost"); 843 return mFbDev->post(mFbDev, buffer->handle); 844 } 845} 846 847int HWComposer::fbCompositionComplete() { 848 if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) 849 return NO_ERROR; 850 851 if (mFbDev->compositionComplete) { 852 return mFbDev->compositionComplete(mFbDev); 853 } else { 854 return INVALID_OPERATION; 855 } 856} 857 858void HWComposer::fbDump(String8& result) { 859 if (mFbDev && mFbDev->common.version >= 1 && mFbDev->dump) { 860 const size_t SIZE = 4096; 861 char buffer[SIZE]; 862 mFbDev->dump(mFbDev, buffer, SIZE); 863 result.append(buffer); 864 } 865} 866 867status_t HWComposer::setOutputBuffer(int32_t id, const sp<Fence>& acquireFence, 868 const sp<GraphicBuffer>& buf) { 869 if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) 870 return BAD_INDEX; 871 if (id < VIRTUAL_DISPLAY_ID_BASE) 872 return INVALID_OPERATION; 873 874 DisplayData& disp(mDisplayData[id]); 875 disp.outbufHandle = buf->handle; 876 disp.outbufAcquireFence = acquireFence; 877 return NO_ERROR; 878} 879 880sp<Fence> HWComposer::getLastRetireFence(int32_t id) const { 881 if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) 882 return Fence::NO_FENCE; 883 return mDisplayData[id].lastRetireFence; 884} 885 886status_t HWComposer::setCursorPositionAsync(int32_t id, const Rect& pos) 887{ 888 if (mHwc->setCursorPositionAsync) { 889 return (status_t)mHwc->setCursorPositionAsync(mHwc, id, pos.left, pos.top); 890 } 891 else { 892 return NO_ERROR; 893 } 894} 895 896/* 897 * Helper template to implement a concrete HWCLayer 898 * This holds the pointer to the concrete hwc layer type 899 * and implements the "iterable" side of HWCLayer. 900 */ 901template<typename CONCRETE, typename HWCTYPE> 902class Iterable : public HWComposer::HWCLayer { 903protected: 904 HWCTYPE* const mLayerList; 905 HWCTYPE* mCurrentLayer; 906 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { } 907 inline HWCTYPE const * getLayer() const { return mCurrentLayer; } 908 inline HWCTYPE* getLayer() { return mCurrentLayer; } 909 virtual ~Iterable() { } 910private: 911 // returns a copy of ourselves 912 virtual HWComposer::HWCLayer* dup() { 913 return new CONCRETE( static_cast<const CONCRETE&>(*this) ); 914 } 915 virtual status_t setLayer(size_t index) { 916 mCurrentLayer = &mLayerList[index]; 917 return NO_ERROR; 918 } 919}; 920 921/* 922 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0. 923 * This implements the HWCLayer side of HWCIterableLayer. 924 */ 925class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> { 926 struct hwc_composer_device_1* mHwc; 927public: 928 HWCLayerVersion1(struct hwc_composer_device_1* hwc, hwc_layer_1_t* layer) 929 : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer), mHwc(hwc) { } 930 931 virtual int32_t getCompositionType() const { 932 return getLayer()->compositionType; 933 } 934 virtual uint32_t getHints() const { 935 return getLayer()->hints; 936 } 937 virtual sp<Fence> getAndResetReleaseFence() { 938 int fd = getLayer()->releaseFenceFd; 939 getLayer()->releaseFenceFd = -1; 940 return fd >= 0 ? new Fence(fd) : Fence::NO_FENCE; 941 } 942 virtual void setAcquireFenceFd(int fenceFd) { 943 getLayer()->acquireFenceFd = fenceFd; 944 } 945 virtual void setPerFrameDefaultState() { 946 //getLayer()->compositionType = HWC_FRAMEBUFFER; 947 } 948 virtual void setPlaneAlpha(uint8_t alpha) { 949 if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) { 950 getLayer()->planeAlpha = alpha; 951 } else { 952 if (alpha < 0xFF) { 953 getLayer()->flags |= HWC_SKIP_LAYER; 954 } 955 } 956 } 957 virtual void setDefaultState() { 958 hwc_layer_1_t* const l = getLayer(); 959 l->compositionType = HWC_FRAMEBUFFER; 960 l->hints = 0; 961 l->flags = HWC_SKIP_LAYER; 962 l->handle = 0; 963 l->transform = 0; 964 l->blending = HWC_BLENDING_NONE; 965 l->visibleRegionScreen.numRects = 0; 966 l->visibleRegionScreen.rects = NULL; 967 l->acquireFenceFd = -1; 968 l->releaseFenceFd = -1; 969 l->planeAlpha = 0xFF; 970 } 971 virtual void setSkip(bool skip) { 972 if (skip) { 973 getLayer()->flags |= HWC_SKIP_LAYER; 974 } else { 975 getLayer()->flags &= ~HWC_SKIP_LAYER; 976 } 977 } 978 virtual void setIsCursorLayerHint(bool isCursor) { 979 if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) { 980 if (isCursor) { 981 getLayer()->flags |= HWC_IS_CURSOR_LAYER; 982 } 983 else { 984 getLayer()->flags &= ~HWC_IS_CURSOR_LAYER; 985 } 986 } 987 } 988 virtual void setBlending(uint32_t blending) { 989 getLayer()->blending = blending; 990 } 991 virtual void setTransform(uint32_t transform) { 992 getLayer()->transform = transform; 993 } 994 virtual void setFrame(const Rect& frame) { 995 getLayer()->displayFrame = reinterpret_cast<hwc_rect_t const&>(frame); 996 } 997 virtual void setCrop(const FloatRect& crop) { 998 if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) { 999 getLayer()->sourceCropf = reinterpret_cast<hwc_frect_t const&>(crop); 1000 } else { 1001 /* 1002 * Since h/w composer didn't support a flot crop rect before version 1.3, 1003 * using integer coordinates instead produces a different output from the GL code in 1004 * Layer::drawWithOpenGL(). The difference can be large if the buffer crop to 1005 * window size ratio is large and a window crop is defined 1006 * (i.e.: if we scale the buffer a lot and we also crop it with a window crop). 1007 */ 1008 hwc_rect_t& r = getLayer()->sourceCrop; 1009 r.left = int(ceilf(crop.left)); 1010 r.top = int(ceilf(crop.top)); 1011 r.right = int(floorf(crop.right)); 1012 r.bottom= int(floorf(crop.bottom)); 1013 } 1014 } 1015 virtual void setVisibleRegionScreen(const Region& reg) { 1016 // Region::getSharedBuffer creates a reference to the underlying 1017 // SharedBuffer of this Region, this reference is freed 1018 // in onDisplayed() 1019 hwc_region_t& visibleRegion = getLayer()->visibleRegionScreen; 1020 SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects); 1021 visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data()); 1022 } 1023 virtual void setSurfaceDamage(const Region& reg) { 1024 if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) { 1025 return; 1026 } 1027 hwc_region_t& surfaceDamage = getLayer()->surfaceDamage; 1028 // We encode default full-screen damage as INVALID_RECT upstream, but as 1029 // 0 rects for HWComposer 1030 if (reg.isRect() && reg.getBounds() == Rect::INVALID_RECT) { 1031 surfaceDamage.numRects = 0; 1032 surfaceDamage.rects = NULL; 1033 return; 1034 } 1035 SharedBuffer const* sb = reg.getSharedBuffer(&surfaceDamage.numRects); 1036 surfaceDamage.rects = reinterpret_cast<hwc_rect_t const *>(sb->data()); 1037 } 1038 virtual void setSidebandStream(const sp<NativeHandle>& stream) { 1039 ALOG_ASSERT(stream->handle() != NULL); 1040 getLayer()->compositionType = HWC_SIDEBAND; 1041 getLayer()->sidebandStream = stream->handle(); 1042 } 1043 virtual void setBuffer(const sp<GraphicBuffer>& buffer) { 1044 if (buffer == 0 || buffer->handle == 0) { 1045 getLayer()->compositionType = HWC_FRAMEBUFFER; 1046 getLayer()->flags |= HWC_SKIP_LAYER; 1047 getLayer()->handle = 0; 1048 } else { 1049 if (getLayer()->compositionType == HWC_SIDEBAND) { 1050 // If this was a sideband layer but the stream was removed, reset 1051 // it to FRAMEBUFFER. The HWC can change it to OVERLAY in prepare. 1052 getLayer()->compositionType = HWC_FRAMEBUFFER; 1053 } 1054 getLayer()->handle = buffer->handle; 1055 } 1056 } 1057 virtual void onDisplayed() { 1058 hwc_region_t& visibleRegion = getLayer()->visibleRegionScreen; 1059 SharedBuffer const* sb = SharedBuffer::bufferFromData(visibleRegion.rects); 1060 if (sb) { 1061 sb->release(); 1062 // not technically needed but safer 1063 visibleRegion.numRects = 0; 1064 visibleRegion.rects = NULL; 1065 } 1066 1067 getLayer()->acquireFenceFd = -1; 1068 1069 if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) { 1070 return; 1071 } 1072 1073 hwc_region_t& surfaceDamage = getLayer()->surfaceDamage; 1074 sb = SharedBuffer::bufferFromData(surfaceDamage.rects); 1075 if (sb) { 1076 sb->release(); 1077 surfaceDamage.numRects = 0; 1078 surfaceDamage.rects = NULL; 1079 } 1080 } 1081}; 1082 1083/* 1084 * returns an iterator initialized at a given index in the layer list 1085 */ 1086HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) { 1087 if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) { 1088 return LayerListIterator(); 1089 } 1090 const DisplayData& disp(mDisplayData[id]); 1091 if (!mHwc || !disp.list || index > disp.list->numHwLayers) { 1092 return LayerListIterator(); 1093 } 1094 return LayerListIterator(new HWCLayerVersion1(mHwc, disp.list->hwLayers), index); 1095} 1096 1097/* 1098 * returns an iterator on the beginning of the layer list 1099 */ 1100HWComposer::LayerListIterator HWComposer::begin(int32_t id) { 1101 return getLayerIterator(id, 0); 1102} 1103 1104/* 1105 * returns an iterator on the end of the layer list 1106 */ 1107HWComposer::LayerListIterator HWComposer::end(int32_t id) { 1108 size_t numLayers = 0; 1109 if (uint32_t(id) <= 31 && mAllocatedDisplayIDs.hasBit(id)) { 1110 const DisplayData& disp(mDisplayData[id]); 1111 if (mHwc && disp.list) { 1112 numLayers = disp.list->numHwLayers; 1113 if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { 1114 // with HWC 1.1, the last layer is always the HWC_FRAMEBUFFER_TARGET, 1115 // which we ignore when iterating through the layer list. 1116 ALOGE_IF(!numLayers, "mDisplayData[%d].list->numHwLayers is 0", id); 1117 if (numLayers) { 1118 numLayers--; 1119 } 1120 } 1121 } 1122 } 1123 return getLayerIterator(id, numLayers); 1124} 1125 1126// Converts a PixelFormat to a human-readable string. Max 11 chars. 1127// (Could use a table of prefab String8 objects.) 1128static String8 getFormatStr(PixelFormat format) { 1129 switch (format) { 1130 case PIXEL_FORMAT_RGBA_8888: return String8("RGBA_8888"); 1131 case PIXEL_FORMAT_RGBX_8888: return String8("RGBx_8888"); 1132 case PIXEL_FORMAT_RGB_888: return String8("RGB_888"); 1133 case PIXEL_FORMAT_RGB_565: return String8("RGB_565"); 1134 case PIXEL_FORMAT_BGRA_8888: return String8("BGRA_8888"); 1135 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: 1136 return String8("ImplDef"); 1137 default: 1138 String8 result; 1139 result.appendFormat("? %08x", format); 1140 return result; 1141 } 1142} 1143 1144void HWComposer::dump(String8& result) const { 1145 if (mHwc) { 1146 result.appendFormat("Hardware Composer state (version %08x):\n", hwcApiVersion(mHwc)); 1147 result.appendFormat(" mDebugForceFakeVSync=%d\n", mDebugForceFakeVSync); 1148 for (size_t i=0 ; i<mNumDisplays ; i++) { 1149 const DisplayData& disp(mDisplayData[i]); 1150 if (!disp.connected) 1151 continue; 1152 1153 const Vector< sp<Layer> >& visibleLayersSortedByZ = 1154 mFlinger->getLayerSortedByZForHwcDisplay(i); 1155 1156 1157 result.appendFormat(" Display[%zd] configurations (* current):\n", i); 1158 for (size_t c = 0; c < disp.configs.size(); ++c) { 1159 const DisplayConfig& config(disp.configs[c]); 1160 result.appendFormat(" %s%zd: %ux%u, xdpi=%f, ydpi=%f, refresh=%" PRId64 "\n", 1161 c == disp.currentConfig ? "* " : "", c, config.width, config.height, 1162 config.xdpi, config.ydpi, config.refresh); 1163 } 1164 1165 if (disp.list) { 1166 result.appendFormat( 1167 " numHwLayers=%zu, flags=%08x\n", 1168 disp.list->numHwLayers, disp.list->flags); 1169 1170 result.append( 1171 " type | handle | hint | flag | tr | blnd | format | source crop (l,t,r,b) | frame | name \n" 1172 "-----------+----------+------+------+----+------+-------------+--------------------------------+------------------------+------\n"); 1173 // " _________ | ________ | ____ | ____ | __ | ____ | ___________ |_____._,_____._,_____._,_____._ |_____,_____,_____,_____ | ___... 1174 for (size_t i=0 ; i<disp.list->numHwLayers ; i++) { 1175 const hwc_layer_1_t&l = disp.list->hwLayers[i]; 1176 int32_t format = -1; 1177 String8 name("unknown"); 1178 1179 if (i < visibleLayersSortedByZ.size()) { 1180 const sp<Layer>& layer(visibleLayersSortedByZ[i]); 1181 const sp<GraphicBuffer>& buffer( 1182 layer->getActiveBuffer()); 1183 if (buffer != NULL) { 1184 format = buffer->getPixelFormat(); 1185 } 1186 name = layer->getName(); 1187 } 1188 1189 int type = l.compositionType; 1190 if (type == HWC_FRAMEBUFFER_TARGET) { 1191 name = "HWC_FRAMEBUFFER_TARGET"; 1192 format = disp.format; 1193 } 1194 1195 static char const* compositionTypeName[] = { 1196 "GLES", 1197 "HWC", 1198 "BKGND", 1199 "FB TARGET", 1200 "SIDEBAND", 1201 "HWC_CURSOR", 1202 "UNKNOWN"}; 1203 if (type >= NELEM(compositionTypeName)) 1204 type = NELEM(compositionTypeName) - 1; 1205 1206 String8 formatStr = getFormatStr(format); 1207 if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) { 1208 result.appendFormat( 1209 " %9s | %08" PRIxPTR " | %04x | %04x | %02x | %04x | %-11s |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d | %s\n", 1210 compositionTypeName[type], 1211 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, formatStr.string(), 1212 l.sourceCropf.left, l.sourceCropf.top, l.sourceCropf.right, l.sourceCropf.bottom, 1213 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom, 1214 name.string()); 1215 } else { 1216 result.appendFormat( 1217 " %9s | %08" PRIxPTR " | %04x | %04x | %02x | %04x | %-11s |%7d,%7d,%7d,%7d |%5d,%5d,%5d,%5d | %s\n", 1218 compositionTypeName[type], 1219 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, formatStr.string(), 1220 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom, 1221 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom, 1222 name.string()); 1223 } 1224 } 1225 } 1226 } 1227 } 1228 1229 if (mHwc && mHwc->dump) { 1230 const size_t SIZE = 4096; 1231 char buffer[SIZE]; 1232 mHwc->dump(mHwc, buffer, SIZE); 1233 result.append(buffer); 1234 } 1235} 1236 1237// --------------------------------------------------------------------------- 1238 1239HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) 1240 : mHwc(hwc), mEnabled(false), 1241 mNextFakeVSync(0), 1242 mRefreshPeriod(hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY)) 1243{ 1244} 1245 1246void HWComposer::VSyncThread::setEnabled(bool enabled) { 1247 Mutex::Autolock _l(mLock); 1248 if (mEnabled != enabled) { 1249 mEnabled = enabled; 1250 mCondition.signal(); 1251 } 1252} 1253 1254void HWComposer::VSyncThread::onFirstRef() { 1255 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); 1256} 1257 1258bool HWComposer::VSyncThread::threadLoop() { 1259 { // scope for lock 1260 Mutex::Autolock _l(mLock); 1261 while (!mEnabled) { 1262 mCondition.wait(mLock); 1263 } 1264 } 1265 1266 const nsecs_t period = mRefreshPeriod; 1267 const nsecs_t now = systemTime(CLOCK_MONOTONIC); 1268 nsecs_t next_vsync = mNextFakeVSync; 1269 nsecs_t sleep = next_vsync - now; 1270 if (sleep < 0) { 1271 // we missed, find where the next vsync should be 1272 sleep = (period - ((now - next_vsync) % period)); 1273 next_vsync = now + sleep; 1274 } 1275 mNextFakeVSync = next_vsync + period; 1276 1277 struct timespec spec; 1278 spec.tv_sec = next_vsync / 1000000000; 1279 spec.tv_nsec = next_vsync % 1000000000; 1280 1281 int err; 1282 do { 1283 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); 1284 } while (err<0 && errno == EINTR); 1285 1286 if (err == 0) { 1287 mHwc.mEventHandler.onVSyncReceived(0, next_vsync); 1288 } 1289 1290 return true; 1291} 1292 1293HWComposer::DisplayData::DisplayData() 1294: configs(), 1295 currentConfig(0), 1296 format(HAL_PIXEL_FORMAT_RGBA_8888), 1297 connected(false), 1298 hasFbComp(false), hasOvComp(false), 1299 capacity(0), list(NULL), 1300 framebufferTarget(NULL), fbTargetHandle(0), 1301 lastRetireFence(Fence::NO_FENCE), lastDisplayFence(Fence::NO_FENCE), 1302 outbufHandle(NULL), outbufAcquireFence(Fence::NO_FENCE), 1303 events(0) 1304{} 1305 1306HWComposer::DisplayData::~DisplayData() { 1307 free(list); 1308} 1309 1310// --------------------------------------------------------------------------- 1311}; // namespace android 1312