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/Vector.h> 26 27 #include <hardware/hardware.h> 28 29 #include <cutils/log.h> 30 31 #include <EGL/egl.h> 32 33 #include "LayerBase.h" 34 #include "HWComposer.h" 35 #include "SurfaceFlinger.h" 36 37 namespace android { 38 // --------------------------------------------------------------------------- 39 40 HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger) 41 : mFlinger(flinger), 42 mModule(0), mHwc(0), mList(0), mCapacity(0), 43 mNumOVLayers(0), mNumFBLayers(0), 44 mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE) 45 { 46 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); 47 LOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); 48 if (err == 0) { 49 err = hwc_open(mModule, &mHwc); 50 LOGE_IF(err, "%s device failed to initialize (%s)", 51 HWC_HARDWARE_COMPOSER, strerror(-err)); 52 if (err == 0) { 53 if (mHwc->registerProcs) { 54 mCBContext.hwc = this; 55 mCBContext.procs.invalidate = &hook_invalidate; 56 mHwc->registerProcs(mHwc, &mCBContext.procs); 57 } 58 } 59 } 60 } 61 62 HWComposer::~HWComposer() { 63 free(mList); 64 if (mHwc) { 65 hwc_close(mHwc); 66 } 67 } 68 69 status_t HWComposer::initCheck() const { 70 return mHwc ? NO_ERROR : NO_INIT; 71 } 72 73 void HWComposer::hook_invalidate(struct hwc_procs* procs) { 74 reinterpret_cast<cb_context *>(procs)->hwc->invalidate(); 75 } 76 77 void HWComposer::invalidate() { 78 mFlinger->repaintEverything(); 79 } 80 81 void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) { 82 mDpy = (hwc_display_t)dpy; 83 mSur = (hwc_surface_t)sur; 84 } 85 86 status_t HWComposer::createWorkList(size_t numLayers) { 87 if (mHwc) { 88 if (!mList || mCapacity < numLayers) { 89 free(mList); 90 size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t); 91 mList = (hwc_layer_list_t*)malloc(size); 92 mCapacity = numLayers; 93 } 94 mList->flags = HWC_GEOMETRY_CHANGED; 95 mList->numHwLayers = numLayers; 96 } 97 return NO_ERROR; 98 } 99 100 status_t HWComposer::prepare() const { 101 int err = mHwc->prepare(mHwc, mList); 102 if (err == NO_ERROR) { 103 size_t numOVLayers = 0; 104 size_t numFBLayers = 0; 105 size_t count = mList->numHwLayers; 106 for (size_t i=0 ; i<count ; i++) { 107 hwc_layer& l(mList->hwLayers[i]); 108 if (l.flags & HWC_SKIP_LAYER) { 109 l.compositionType = HWC_FRAMEBUFFER; 110 } 111 switch (l.compositionType) { 112 case HWC_OVERLAY: 113 numOVLayers++; 114 break; 115 case HWC_FRAMEBUFFER: 116 numFBLayers++; 117 break; 118 } 119 } 120 mNumOVLayers = numOVLayers; 121 mNumFBLayers = numFBLayers; 122 } 123 return (status_t)err; 124 } 125 126 size_t HWComposer::getLayerCount(int type) const { 127 switch (type) { 128 case HWC_OVERLAY: 129 return mNumOVLayers; 130 case HWC_FRAMEBUFFER: 131 return mNumFBLayers; 132 } 133 return 0; 134 } 135 136 status_t HWComposer::commit() const { 137 int err = mHwc->set(mHwc, mDpy, mSur, mList); 138 if (mList) { 139 mList->flags &= ~HWC_GEOMETRY_CHANGED; 140 } 141 return (status_t)err; 142 } 143 144 status_t HWComposer::release() const { 145 if (mHwc) { 146 int err = mHwc->set(mHwc, NULL, NULL, NULL); 147 return (status_t)err; 148 } 149 return NO_ERROR; 150 } 151 152 status_t HWComposer::disable() { 153 if (mHwc) { 154 free(mList); 155 mList = NULL; 156 int err = mHwc->prepare(mHwc, NULL); 157 return (status_t)err; 158 } 159 return NO_ERROR; 160 } 161 162 size_t HWComposer::getNumLayers() const { 163 return mList ? mList->numHwLayers : 0; 164 } 165 166 hwc_layer_t* HWComposer::getLayers() const { 167 return mList ? mList->hwLayers : 0; 168 } 169 170 void HWComposer::dump(String8& result, char* buffer, size_t SIZE, 171 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const { 172 if (mHwc && mList) { 173 result.append("Hardware Composer state:\n"); 174 175 snprintf(buffer, SIZE, " numHwLayers=%u, flags=%08x\n", 176 mList->numHwLayers, mList->flags); 177 result.append(buffer); 178 result.append( 179 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n" 180 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n"); 181 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____] 182 for (size_t i=0 ; i<mList->numHwLayers ; i++) { 183 const hwc_layer_t& l(mList->hwLayers[i]); 184 const sp<LayerBase> layer(visibleLayersSortedByZ[i]); 185 int32_t format = -1; 186 if (layer->getLayer() != NULL) { 187 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer()); 188 if (buffer != NULL) { 189 format = buffer->getPixelFormat(); 190 } 191 } 192 snprintf(buffer, SIZE, 193 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n", 194 l.compositionType ? "OVERLAY" : "FB", 195 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format, 196 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom, 197 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom, 198 layer->getName().string()); 199 result.append(buffer); 200 } 201 } 202 if (mHwc && mHwc->common.version >= 1 && mHwc->dump) { 203 mHwc->dump(mHwc, buffer, SIZE); 204 result.append(buffer); 205 } 206 } 207 208 // --------------------------------------------------------------------------- 209 }; // namespace android 210