HWComposer.cpp revision 3eb38cb33e41ce40dd1094bdec850f0fca9f8a53
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdint.h> 18#include <stdio.h> 19#include <stdlib.h> 20#include <string.h> 21#include <sys/types.h> 22 23#include <utils/Errors.h> 24#include <utils/String8.h> 25#include <utils/Thread.h> 26#include <utils/Vector.h> 27 28#include <hardware/hardware.h> 29#include <hardware/hwcomposer.h> 30 31#include <cutils/log.h> 32 33#include <EGL/egl.h> 34 35#include "LayerBase.h" 36#include "HWComposer.h" 37#include "SurfaceFlinger.h" 38 39namespace android { 40// --------------------------------------------------------------------------- 41 42HWComposer::HWComposer( 43 const sp<SurfaceFlinger>& flinger, 44 EventHandler& handler, 45 nsecs_t refreshPeriod) 46 : mFlinger(flinger), 47 mModule(0), mHwc(0), mList(0), mCapacity(0), 48 mNumOVLayers(0), mNumFBLayers(0), 49 mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE), 50 mEventHandler(handler), 51 mRefreshPeriod(refreshPeriod) 52{ 53 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); 54 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); 55 if (err == 0) { 56 err = hwc_open(mModule, &mHwc); 57 ALOGE_IF(err, "%s device failed to initialize (%s)", 58 HWC_HARDWARE_COMPOSER, strerror(-err)); 59 if (err == 0) { 60 if (mHwc->registerProcs) { 61 mCBContext.hwc = this; 62 mCBContext.procs.invalidate = &hook_invalidate; 63 mCBContext.procs.vsync = &hook_vsync; 64 mHwc->registerProcs(mHwc, &mCBContext.procs); 65 memset(mCBContext.procs.zero, 0, sizeof(mCBContext.procs.zero)); 66 } 67 68 if (mHwc->common.version < HWC_DEVICE_API_VERSION_0_3) { 69 // we don't have VSYNC support, we need to fake it 70 mVSyncThread = new VSyncThread(*this); 71 } 72 } 73 } 74} 75 76HWComposer::~HWComposer() { 77 free(mList); 78 if (mVSyncThread != NULL) { 79 mVSyncThread->requestExitAndWait(); 80 } 81 if (mHwc) { 82 hwc_close(mHwc); 83 } 84} 85 86status_t HWComposer::initCheck() const { 87 return mHwc ? NO_ERROR : NO_INIT; 88} 89 90void HWComposer::hook_invalidate(struct hwc_procs* procs) { 91 reinterpret_cast<cb_context *>(procs)->hwc->invalidate(); 92} 93 94void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) { 95 reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp); 96} 97 98void HWComposer::invalidate() { 99 mFlinger->repaintEverything(); 100} 101 102void HWComposer::vsync(int dpy, int64_t timestamp) { 103 mEventHandler.onVSyncReceived(dpy, timestamp); 104} 105 106status_t HWComposer::eventControl(int event, int enabled) { 107 status_t err = NO_ERROR; 108 if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { 109 err = mHwc->methods->eventControl(mHwc, event, enabled); 110 } else { 111 if (mVSyncThread != NULL) { 112 mVSyncThread->setEnabled(enabled); 113 } else { 114 err = BAD_VALUE; 115 } 116 } 117 return err; 118} 119 120void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) { 121 mDpy = (hwc_display_t)dpy; 122 mSur = (hwc_surface_t)sur; 123} 124 125status_t HWComposer::createWorkList(size_t numLayers) { 126 if (mHwc) { 127 if (!mList || mCapacity < numLayers) { 128 free(mList); 129 size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t); 130 mList = (hwc_layer_list_t*)malloc(size); 131 mCapacity = numLayers; 132 } 133 mList->flags = HWC_GEOMETRY_CHANGED; 134 mList->numHwLayers = numLayers; 135 } 136 return NO_ERROR; 137} 138 139status_t HWComposer::prepare() const { 140 int err = mHwc->prepare(mHwc, mList); 141 if (err == NO_ERROR) { 142 size_t numOVLayers = 0; 143 size_t numFBLayers = 0; 144 size_t count = mList->numHwLayers; 145 for (size_t i=0 ; i<count ; i++) { 146 hwc_layer& l(mList->hwLayers[i]); 147 if (l.flags & HWC_SKIP_LAYER) { 148 l.compositionType = HWC_FRAMEBUFFER; 149 } 150 switch (l.compositionType) { 151 case HWC_OVERLAY: 152 numOVLayers++; 153 break; 154 case HWC_FRAMEBUFFER: 155 numFBLayers++; 156 break; 157 } 158 } 159 mNumOVLayers = numOVLayers; 160 mNumFBLayers = numFBLayers; 161 } 162 return (status_t)err; 163} 164 165size_t HWComposer::getLayerCount(int type) const { 166 switch (type) { 167 case HWC_OVERLAY: 168 return mNumOVLayers; 169 case HWC_FRAMEBUFFER: 170 return mNumFBLayers; 171 } 172 return 0; 173} 174 175status_t HWComposer::commit() const { 176 int err = mHwc->set(mHwc, mDpy, mSur, mList); 177 if (mList) { 178 mList->flags &= ~HWC_GEOMETRY_CHANGED; 179 } 180 return (status_t)err; 181} 182 183status_t HWComposer::release() const { 184 if (mHwc) { 185 int err = mHwc->set(mHwc, NULL, NULL, NULL); 186 return (status_t)err; 187 } 188 return NO_ERROR; 189} 190 191status_t HWComposer::disable() { 192 if (mHwc) { 193 free(mList); 194 mList = NULL; 195 int err = mHwc->prepare(mHwc, NULL); 196 return (status_t)err; 197 } 198 return NO_ERROR; 199} 200 201size_t HWComposer::getNumLayers() const { 202 return mList ? mList->numHwLayers : 0; 203} 204 205hwc_layer_t* HWComposer::getLayers() const { 206 return mList ? mList->hwLayers : 0; 207} 208 209void HWComposer::dump(String8& result, char* buffer, size_t SIZE, 210 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const { 211 if (mHwc && mList) { 212 result.append("Hardware Composer state:\n"); 213 214 snprintf(buffer, SIZE, " numHwLayers=%u, flags=%08x\n", 215 mList->numHwLayers, mList->flags); 216 result.append(buffer); 217 result.append( 218 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n" 219 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n"); 220 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____] 221 for (size_t i=0 ; i<mList->numHwLayers ; i++) { 222 const hwc_layer_t& l(mList->hwLayers[i]); 223 const sp<LayerBase> layer(visibleLayersSortedByZ[i]); 224 int32_t format = -1; 225 if (layer->getLayer() != NULL) { 226 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer()); 227 if (buffer != NULL) { 228 format = buffer->getPixelFormat(); 229 } 230 } 231 snprintf(buffer, SIZE, 232 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n", 233 l.compositionType ? "OVERLAY" : "FB", 234 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format, 235 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom, 236 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom, 237 layer->getName().string()); 238 result.append(buffer); 239 } 240 } 241 if (mHwc && mHwc->common.version >= 1 && mHwc->dump) { 242 mHwc->dump(mHwc, buffer, SIZE); 243 result.append(buffer); 244 } 245} 246 247// --------------------------------------------------------------------------- 248}; // namespace android 249