blob: a44b1e1a68cd85f5cc9abaf7803f1e8311684e59 [file] [log] [blame]
Mathias Agopiana350ff92010-08-10 17:14:02 -07001/*
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
Mathias Agopian2965b262012-04-08 15:13:32 -070017#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
Jesse Hall5880cc52012-06-05 23:40:32 -070019// Uncomment this to remove support for HWC_DEVICE_API_VERSION_0_3 and older
Mathias Agopian30bcc612012-08-22 15:39:48 -070020#define HWC_REMOVE_DEPRECATED_VERSIONS 1
Jesse Hall5880cc52012-06-05 23:40:32 -070021
Mathias Agopiana350ff92010-08-10 17:14:02 -070022#include <stdint.h>
Mathias Agopianf1352df2010-08-11 17:31:33 -070023#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070026#include <sys/types.h>
27
28#include <utils/Errors.h>
Mathias Agopian83727852010-09-23 18:13:21 -070029#include <utils/String8.h>
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070030#include <utils/Thread.h>
Mathias Agopian2965b262012-04-08 15:13:32 -070031#include <utils/Trace.h>
Mathias Agopian22da60c2011-09-09 00:49:11 -070032#include <utils/Vector.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070033
Mathias Agopian921e6ac2012-07-23 23:11:29 -070034#include <ui/GraphicBuffer.h>
35
Mathias Agopiana350ff92010-08-10 17:14:02 -070036#include <hardware/hardware.h>
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070037#include <hardware/hwcomposer.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070038
39#include <cutils/log.h>
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -070040#include <cutils/properties.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070041
Mathias Agopian921e6ac2012-07-23 23:11:29 -070042#include "Layer.h" // needed only for debugging
Mathias Agopian22da60c2011-09-09 00:49:11 -070043#include "LayerBase.h"
Mathias Agopiana350ff92010-08-10 17:14:02 -070044#include "HWComposer.h"
Mathias Agopianc7d14e22011-08-01 16:32:21 -070045#include "SurfaceFlinger.h"
Mathias Agopiana350ff92010-08-10 17:14:02 -070046
47namespace android {
Jesse Hall5880cc52012-06-05 23:40:32 -070048
Jesse Hall5880cc52012-06-05 23:40:32 -070049static bool hwcHasVersion(const hwc_composer_device_1_t* hwc, uint32_t version) {
Mathias Agopian30bcc612012-08-22 15:39:48 -070050 return hwc->common.version >= version;
Jesse Hallbbd164a2012-08-21 12:05:09 -070051}
52
Mathias Agopiana350ff92010-08-10 17:14:02 -070053// ---------------------------------------------------------------------------
54
Mathias Agopian3e8b8532012-05-13 20:42:01 -070055struct HWComposer::cb_context {
56 struct callbacks : public hwc_procs_t {
57 // these are here to facilitate the transition when adding
58 // new callbacks (an implementation can check for NULL before
59 // calling a new callback).
60 void (*zero[4])(void);
61 };
62 callbacks procs;
63 HWComposer* hwc;
64};
65
66// ---------------------------------------------------------------------------
67
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070068HWComposer::HWComposer(
69 const sp<SurfaceFlinger>& flinger,
Mathias Agopian8b736f12012-08-13 17:54:26 -070070 EventHandler& handler,
71 framebuffer_device_t const* fbDev)
Mathias Agopianc7d14e22011-08-01 16:32:21 -070072 : mFlinger(flinger),
Jesse Hall8f971ff2012-08-22 11:50:00 -070073 mModule(0), mHwc(0), mNumDisplays(1), mCapacity(0),
Mathias Agopian3e8b8532012-05-13 20:42:01 -070074 mCBContext(new cb_context),
Mathias Agopiane60b0682012-08-21 23:34:09 -070075 mEventHandler(handler),
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -070076 mVSyncCount(0), mDebugForceFakeVSync(false)
Mathias Agopiana350ff92010-08-10 17:14:02 -070077{
Mathias Agopiane60b0682012-08-21 23:34:09 -070078 for (size_t i =0 ; i<MAX_DISPLAYS ; i++) {
79 mLists[i] = 0;
80 }
Jesse Hallb685c542012-07-31 14:32:56 -070081
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -070082 char value[PROPERTY_VALUE_MAX];
83 property_get("debug.sf.no_hw_vsync", value, "0");
84 mDebugForceFakeVSync = atoi(value);
85
Mathias Agopian028508c2012-07-25 21:12:12 -070086 bool needVSyncThread = true;
Mathias Agopiana350ff92010-08-10 17:14:02 -070087 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
Steve Block32397c12012-01-05 23:22:43 +000088 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
Mathias Agopiana350ff92010-08-10 17:14:02 -070089 if (err == 0) {
Jesse Hall5880cc52012-06-05 23:40:32 -070090 err = hwc_open_1(mModule, &mHwc);
Steve Blocke6f43dd2012-01-06 19:20:56 +000091 ALOGE_IF(err, "%s device failed to initialize (%s)",
Mathias Agopiana350ff92010-08-10 17:14:02 -070092 HWC_HARDWARE_COMPOSER, strerror(-err));
Mathias Agopianc7d14e22011-08-01 16:32:21 -070093 if (err == 0) {
Mathias Agopian30bcc612012-08-22 15:39:48 -070094 if (mHwc->common.version < HWC_DEVICE_API_VERSION_1_0) {
Jesse Hall5880cc52012-06-05 23:40:32 -070095 ALOGE("%s device version %#x too old, will not be used",
96 HWC_HARDWARE_COMPOSER, mHwc->common.version);
97 hwc_close_1(mHwc);
98 mHwc = NULL;
99 }
100 }
101
102 if (mHwc) {
Jesse Hallbbd164a2012-08-21 12:05:09 -0700103 if (mHwc->registerProcs) {
104 mCBContext->hwc = this;
105 mCBContext->procs.invalidate = &hook_invalidate;
106 mCBContext->procs.vsync = &hook_vsync;
107 memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
108 mHwc->registerProcs(mHwc, &mCBContext->procs);
109 }
110
Mathias Agopiane60b0682012-08-21 23:34:09 -0700111 // these IDs are always reserved
112 mTokens.markBit(HWC_DISPLAY_PRIMARY);
113 mTokens.markBit(HWC_DISPLAY_EXTERNAL);
114
Jesse Hallb685c542012-07-31 14:32:56 -0700115 // always turn vsync off when we start
116 needVSyncThread = false;
Mathias Agopian888c8222012-08-04 21:10:38 -0700117
Mathias Agopian30bcc612012-08-22 15:39:48 -0700118 mHwc->eventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
119
120 int period;
121 if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) {
122 mDisplayData[0].refresh = nsecs_t(period);
Mathias Agopian028508c2012-07-25 21:12:12 -0700123 }
Jesse Hallb685c542012-07-31 14:32:56 -0700124
Jesse Hall8f971ff2012-08-22 11:50:00 -0700125 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
126 mNumDisplays = HWC_NUM_DISPLAY_TYPES;
127
Jesse Hallb685c542012-07-31 14:32:56 -0700128 // create initial empty display contents for display 0
Jesse Hall8f971ff2012-08-22 11:50:00 -0700129 createWorkList(HWC_DISPLAY_PRIMARY, 0);
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700130 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700131 }
132
Mathias Agopian8b736f12012-08-13 17:54:26 -0700133
134 if (fbDev) {
Mathias Agopiane60b0682012-08-21 23:34:09 -0700135 if (mDisplayData[HWC_DISPLAY_PRIMARY].refresh == 0) {
136 mDisplayData[HWC_DISPLAY_PRIMARY].refresh = nsecs_t(1e9 / fbDev->fps);
137 ALOGW("getting VSYNC period from fb HAL: %lld", mDisplayData[0].refresh);
Mathias Agopian888c8222012-08-04 21:10:38 -0700138 }
Mathias Agopiane60b0682012-08-21 23:34:09 -0700139 mDisplayData[HWC_DISPLAY_PRIMARY].xdpi = fbDev->xdpi;
140 mDisplayData[HWC_DISPLAY_PRIMARY].ydpi = fbDev->ydpi;
Mathias Agopian888c8222012-08-04 21:10:38 -0700141 }
142
Mathias Agopiane60b0682012-08-21 23:34:09 -0700143 if (mDisplayData[HWC_DISPLAY_PRIMARY].refresh == 0) {
144 mDisplayData[HWC_DISPLAY_PRIMARY].refresh = nsecs_t(1e9 / 60.0);
145 ALOGW("getting VSYNC period thin air: %lld", mDisplayData[0].refresh);
Mathias Agopian888c8222012-08-04 21:10:38 -0700146 }
147
Mathias Agopian3a778712012-04-09 14:16:47 -0700148 if (needVSyncThread) {
149 // we don't have VSYNC support, we need to fake it
150 mVSyncThread = new VSyncThread(*this);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700151 }
152}
153
154HWComposer::~HWComposer() {
Mathias Agopian30bcc612012-08-22 15:39:48 -0700155 mHwc->eventControl(mHwc, 0, EVENT_VSYNC, 0);
Mathias Agopiane60b0682012-08-21 23:34:09 -0700156 for (size_t i = 0; i < MAX_DISPLAYS; i++) {
Jesse Hallb685c542012-07-31 14:32:56 -0700157 free(mLists[i]);
Mathias Agopiane60b0682012-08-21 23:34:09 -0700158 }
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700159 if (mVSyncThread != NULL) {
160 mVSyncThread->requestExitAndWait();
161 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700162 if (mHwc) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700163 hwc_close_1(mHwc);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700164 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700165 delete mCBContext;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700166}
167
168status_t HWComposer::initCheck() const {
169 return mHwc ? NO_ERROR : NO_INIT;
170}
171
Jesse Hallbbd164a2012-08-21 12:05:09 -0700172void HWComposer::hook_invalidate(const struct hwc_procs* procs) {
173 cb_context* ctx = reinterpret_cast<cb_context*>(
174 const_cast<hwc_procs_t*>(procs));
175 ctx->hwc->invalidate();
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700176}
177
Jesse Hallbbd164a2012-08-21 12:05:09 -0700178void HWComposer::hook_vsync(const struct hwc_procs* procs, int dpy,
179 int64_t timestamp) {
180 cb_context* ctx = reinterpret_cast<cb_context*>(
181 const_cast<hwc_procs_t*>(procs));
182 ctx->hwc->vsync(dpy, timestamp);
Mathias Agopian31d28432012-04-03 16:31:39 -0700183}
184
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700185void HWComposer::invalidate() {
Mathias Agopiane2c2f922011-10-05 15:00:22 -0700186 mFlinger->repaintEverything();
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700187}
188
Mathias Agopian31d28432012-04-03 16:31:39 -0700189void HWComposer::vsync(int dpy, int64_t timestamp) {
Mathias Agopian2965b262012-04-08 15:13:32 -0700190 ATRACE_INT("VSYNC", ++mVSyncCount&1);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700191 mEventHandler.onVSyncReceived(dpy, timestamp);
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700192 Mutex::Autolock _l(mLock);
193 mLastHwVSync = timestamp;
194}
195
Mathias Agopiane60b0682012-08-21 23:34:09 -0700196int32_t HWComposer::allocateDisplayId() {
197 if (mTokens.isFull()) {
198 return NO_MEMORY;
199 }
200
201 // FIXME: for now we don't support h/w composition wifi displays
202 return -1;
203
204 int32_t id = mTokens.firstUnmarkedBit();
205 mTokens.markBit(id);
206 return id;
207}
208
209status_t HWComposer::freeDisplayId(int32_t id) {
210 if (id < MAX_DISPLAYS) {
211 return BAD_VALUE;
212 }
213 if (!mTokens.hasBit(id)) {
214 return BAD_INDEX;
215 }
216 mTokens.clearBit(id);
217 return NO_ERROR;
218}
219
Mathias Agopian888c8222012-08-04 21:10:38 -0700220nsecs_t HWComposer::getRefreshPeriod() const {
Mathias Agopiane60b0682012-08-21 23:34:09 -0700221 return mDisplayData[0].refresh;
Mathias Agopian888c8222012-08-04 21:10:38 -0700222}
223
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700224nsecs_t HWComposer::getRefreshTimestamp() const {
225 // this returns the last refresh timestamp.
226 // if the last one is not available, we estimate it based on
227 // the refresh period and whatever closest timestamp we have.
228 Mutex::Autolock _l(mLock);
229 nsecs_t now = systemTime(CLOCK_MONOTONIC);
Mathias Agopiane60b0682012-08-21 23:34:09 -0700230 return now - ((now - mLastHwVSync) % mDisplayData[0].refresh);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700231}
232
Mathias Agopian8b736f12012-08-13 17:54:26 -0700233float HWComposer::getDpiX() const {
Mathias Agopiane60b0682012-08-21 23:34:09 -0700234 return mDisplayData[HWC_DISPLAY_PRIMARY].xdpi;
Mathias Agopian8b736f12012-08-13 17:54:26 -0700235}
236
237float HWComposer::getDpiY() const {
Mathias Agopiane60b0682012-08-21 23:34:09 -0700238 return mDisplayData[HWC_DISPLAY_PRIMARY].ydpi;
Mathias Agopian8b736f12012-08-13 17:54:26 -0700239}
240
Mathias Agopian03e40722012-04-26 16:11:59 -0700241void HWComposer::eventControl(int event, int enabled) {
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700242 status_t err = NO_ERROR;
Mathias Agopian30bcc612012-08-22 15:39:48 -0700243 if (mHwc) {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700244 if (!mDebugForceFakeVSync) {
Mathias Agopian30bcc612012-08-22 15:39:48 -0700245 err = mHwc->eventControl(mHwc, 0, event, enabled);
Mathias Agopian03e40722012-04-26 16:11:59 -0700246 // error here should not happen -- not sure what we should
247 // do if it does.
248 ALOGE_IF(err, "eventControl(%d, %d) failed %s",
249 event, enabled, strerror(-err));
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700250 }
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700251 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700252
253 if (err == NO_ERROR && mVSyncThread != NULL) {
254 mVSyncThread->setEnabled(enabled);
255 }
Mathias Agopian31d28432012-04-03 16:31:39 -0700256}
257
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700258status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
Mathias Agopiane60b0682012-08-21 23:34:09 -0700259 if (!mTokens.hasBit(id)) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700260 return BAD_INDEX;
Mathias Agopiane60b0682012-08-21 23:34:09 -0700261 }
Mathias Agopian1e260872012-08-08 18:35:12 -0700262
Mathias Agopiane60b0682012-08-21 23:34:09 -0700263 // FIXME: handle multiple displays
Mathias Agopian45721772010-08-12 15:03:26 -0700264 if (mHwc) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700265 // TODO: must handle multiple displays here
Jesse Hallb685c542012-07-31 14:32:56 -0700266 // mLists[0] is NULL only when this is called from the constructor
267 if (!mLists[0] || mCapacity < numLayers) {
268 free(mLists[0]);
Mathias Agopian30bcc612012-08-22 15:39:48 -0700269 size_t size = sizeof(hwc_display_contents_1_t) + numLayers * sizeof(hwc_layer_1_t);
Jesse Hallb685c542012-07-31 14:32:56 -0700270 mLists[0] = (hwc_display_contents_1_t*)malloc(size);
Mathias Agopian45721772010-08-12 15:03:26 -0700271 mCapacity = numLayers;
272 }
Mathias Agopian30bcc612012-08-22 15:39:48 -0700273 mLists[0]->flags = HWC_GEOMETRY_CHANGED;
274 mLists[0]->numHwLayers = numLayers;
275 mLists[0]->flipFenceFd = -1;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700276 }
277 return NO_ERROR;
278}
279
Mathias Agopiane60b0682012-08-21 23:34:09 -0700280status_t HWComposer::prepare() {
Mathias Agopian30bcc612012-08-22 15:39:48 -0700281 int err = mHwc->prepare(mHwc, mNumDisplays,
Jesse Hallb685c542012-07-31 14:32:56 -0700282 const_cast<hwc_display_contents_1_t**>(mLists));
Mathias Agopiane60b0682012-08-21 23:34:09 -0700283
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700284 if (err == NO_ERROR) {
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700285
286 // here we're just making sure that "skip" layers are set
287 // to HWC_FRAMEBUFFER and we're also counting how many layers
288 // we have of each type.
289 // It would be nice if we could get rid of this entirely, which I
290 // think is almost possible.
291
292 // TODO: must handle multiple displays here
Mathias Agopian30bcc612012-08-22 15:39:48 -0700293
294 size_t count = getNumLayers(0);
295 struct hwc_display_contents_1* disp = mLists[0];
296 mDisplayData[0].hasFbComp = false;
297 mDisplayData[0].hasOvComp = false;
298 for (size_t i=0 ; i<count ; i++) {
299 hwc_layer_1_t* l = &disp->hwLayers[i];
300 if (l->flags & HWC_SKIP_LAYER) {
301 l->compositionType = HWC_FRAMEBUFFER;
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700302 }
Mathias Agopian30bcc612012-08-22 15:39:48 -0700303 if (l->compositionType == HWC_FRAMEBUFFER)
304 mDisplayData[HWC_DISPLAY_PRIMARY].hasFbComp = true;
305 if (l->compositionType == HWC_OVERLAY)
306 mDisplayData[HWC_DISPLAY_PRIMARY].hasOvComp = true;
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700307 }
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700308 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700309 return (status_t)err;
310}
311
Mathias Agopiane60b0682012-08-21 23:34:09 -0700312bool HWComposer::hasHwcComposition(int32_t id) const {
313 if (!mTokens.hasBit(id))
314 return false;
315 return mDisplayData[id].hasOvComp;
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700316}
317
Mathias Agopiane60b0682012-08-21 23:34:09 -0700318bool HWComposer::hasGlesComposition(int32_t id) const {
319 if (!mTokens.hasBit(id))
320 return false;
321 return mDisplayData[id].hasFbComp;
322}
323
Mathias Agopian30bcc612012-08-22 15:39:48 -0700324status_t HWComposer::commit() {
Mathias Agopian86303202012-07-24 22:46:10 -0700325 int err = NO_ERROR;
326 if (mHwc) {
Mathias Agopian30bcc612012-08-22 15:39:48 -0700327 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
328 mLists[0]->dpy = EGL_NO_DISPLAY;
329 mLists[0]->sur = EGL_NO_SURFACE;
330 } else {
331 // On version 1.0, the OpenGL ES target surface is communicated
332 // by the (dpy, sur) fields
333 mLists[0]->dpy = eglGetCurrentDisplay();
334 mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW);
Mathias Agopian86303202012-07-24 22:46:10 -0700335 }
Mathias Agopian30bcc612012-08-22 15:39:48 -0700336 err = mHwc->set(mHwc, mNumDisplays, mLists);
337 if (mLists[0]->flipFenceFd != -1) {
338 close(mLists[0]->flipFenceFd);
339 mLists[0]->flipFenceFd = -1;
340 }
341 mLists[0]->flags &= ~HWC_GEOMETRY_CHANGED;
Mathias Agopian58959342010-10-07 14:57:04 -0700342 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700343 return (status_t)err;
344}
345
Antti Hatalaf5f27122010-09-09 02:33:05 -0700346status_t HWComposer::release() const {
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700347 if (mHwc) {
Mathias Agopian30bcc612012-08-22 15:39:48 -0700348 mHwc->eventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
349 return (status_t)mHwc->blank(mHwc, 0, 1);
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700350 }
351 return NO_ERROR;
352}
353
Colin Cross10fbdb62012-07-12 17:56:34 -0700354status_t HWComposer::acquire() const {
355 if (mHwc) {
Mathias Agopian30bcc612012-08-22 15:39:48 -0700356 return (status_t)mHwc->blank(mHwc, 0, 0);
Colin Cross10fbdb62012-07-12 17:56:34 -0700357 }
Colin Cross10fbdb62012-07-12 17:56:34 -0700358 return NO_ERROR;
359}
360
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700361status_t HWComposer::disable() {
362 if (mHwc) {
Mathias Agopian30bcc612012-08-22 15:39:48 -0700363 mLists[0]->numHwLayers = 0;
364 int err = mHwc->prepare(mHwc, mNumDisplays, mLists);
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700365 return (status_t)err;
366 }
367 return NO_ERROR;
Antti Hatalaf5f27122010-09-09 02:33:05 -0700368}
369
Mathias Agopian1e260872012-08-08 18:35:12 -0700370size_t HWComposer::getNumLayers(int32_t id) const { // FIXME: handle multiple displays
Mathias Agopian30bcc612012-08-22 15:39:48 -0700371 return mHwc ? mLists[0]->numHwLayers : 0;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700372}
373
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700374/*
375 * Helper template to implement a concrete HWCLayer
376 * This holds the pointer to the concrete hwc layer type
377 * and implements the "iterable" side of HWCLayer.
378 */
379template<typename CONCRETE, typename HWCTYPE>
380class Iterable : public HWComposer::HWCLayer {
381protected:
382 HWCTYPE* const mLayerList;
383 HWCTYPE* mCurrentLayer;
384 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
385 inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
386 inline HWCTYPE* getLayer() { return mCurrentLayer; }
387 virtual ~Iterable() { }
388private:
389 // returns a copy of ourselves
390 virtual HWComposer::HWCLayer* dup() {
391 return new CONCRETE( static_cast<const CONCRETE&>(*this) );
392 }
393 virtual status_t setLayer(size_t index) {
394 mCurrentLayer = &mLayerList[index];
395 return NO_ERROR;
396 }
397};
398
Jesse Hall5880cc52012-06-05 23:40:32 -0700399/*
400 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
401 * This implements the HWCLayer side of HWCIterableLayer.
402 */
403class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> {
404public:
405 HWCLayerVersion1(hwc_layer_1_t* layer)
406 : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer) { }
407
408 virtual int32_t getCompositionType() const {
409 return getLayer()->compositionType;
410 }
411 virtual uint32_t getHints() const {
412 return getLayer()->hints;
413 }
Jesse Hallef194142012-06-14 14:45:17 -0700414 virtual int getAndResetReleaseFenceFd() {
415 int fd = getLayer()->releaseFenceFd;
416 getLayer()->releaseFenceFd = -1;
417 return fd;
418 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700419 virtual void setAcquireFenceFd(int fenceFd) {
420 getLayer()->acquireFenceFd = fenceFd;
421 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700422
423 virtual void setDefaultState() {
424 getLayer()->compositionType = HWC_FRAMEBUFFER;
425 getLayer()->hints = 0;
426 getLayer()->flags = HWC_SKIP_LAYER;
427 getLayer()->transform = 0;
428 getLayer()->blending = HWC_BLENDING_NONE;
429 getLayer()->visibleRegionScreen.numRects = 0;
430 getLayer()->visibleRegionScreen.rects = NULL;
431 getLayer()->acquireFenceFd = -1;
432 getLayer()->releaseFenceFd = -1;
433 }
434 virtual void setSkip(bool skip) {
435 if (skip) {
436 getLayer()->flags |= HWC_SKIP_LAYER;
437 } else {
438 getLayer()->flags &= ~HWC_SKIP_LAYER;
439 }
440 }
441 virtual void setBlending(uint32_t blending) {
442 getLayer()->blending = blending;
443 }
444 virtual void setTransform(uint32_t transform) {
445 getLayer()->transform = transform;
446 }
447 virtual void setFrame(const Rect& frame) {
448 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
449 }
450 virtual void setCrop(const Rect& crop) {
451 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
452 }
453 virtual void setVisibleRegionScreen(const Region& reg) {
454 getLayer()->visibleRegionScreen.rects =
455 reinterpret_cast<hwc_rect_t const *>(
456 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
457 }
458 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
459 if (buffer == 0 || buffer->handle == 0) {
460 getLayer()->compositionType = HWC_FRAMEBUFFER;
461 getLayer()->flags |= HWC_SKIP_LAYER;
462 getLayer()->handle = 0;
463 } else {
464 getLayer()->handle = buffer->handle;
465 }
466 }
467};
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700468
469/*
470 * returns an iterator initialized at a given index in the layer list
471 */
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700472HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) {
Mathias Agopiane60b0682012-08-21 23:34:09 -0700473 if (!mTokens.hasBit(id))
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700474 return LayerListIterator();
475
Mathias Agopiane60b0682012-08-21 23:34:09 -0700476 // FIXME: handle multiple displays
Mathias Agopian30bcc612012-08-22 15:39:48 -0700477 if (!mHwc || index > mLists[0]->numHwLayers)
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700478 return LayerListIterator();
Mathias Agopian30bcc612012-08-22 15:39:48 -0700479
480 return LayerListIterator(new HWCLayerVersion1(mLists[0]->hwLayers), index);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700481}
482
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700483/*
484 * returns an iterator on the beginning of the layer list
485 */
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700486HWComposer::LayerListIterator HWComposer::begin(int32_t id) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700487 return getLayerIterator(id, 0);
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700488}
489
490/*
491 * returns an iterator on the end of the layer list
492 */
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700493HWComposer::LayerListIterator HWComposer::end(int32_t id) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700494 return getLayerIterator(id, getNumLayers(id));
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700495}
496
Mathias Agopian22da60c2011-09-09 00:49:11 -0700497void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
498 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
Jesse Hallb685c542012-07-31 14:32:56 -0700499 if (mHwc) {
Mathias Agopian83727852010-09-23 18:13:21 -0700500 result.append("Hardware Composer state:\n");
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700501 result.appendFormat(" mDebugForceFakeVSync=%d\n",
502 mDebugForceFakeVSync);
503 result.appendFormat(" numHwLayers=%u, flags=%08x\n",
Mathias Agopian30bcc612012-08-22 15:39:48 -0700504 mLists[0]->numHwLayers, mLists[0]->flags);
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700505 result.append(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700506 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n"
507 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
508 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
Mathias Agopian30bcc612012-08-22 15:39:48 -0700509 for (size_t i=0 ; i<mLists[0]->numHwLayers ; i++) {
510 hwc_layer_1_t const* lp= &mLists[0]->hwLayers[i];
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700511 const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
512 int32_t format = -1;
513 if (layer->getLayer() != NULL) {
514 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
515 if (buffer != NULL) {
516 format = buffer->getPixelFormat();
517 }
518 }
Mathias Agopian1e260872012-08-08 18:35:12 -0700519 const hwc_layer_1_t& l(*lp);
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700520 result.appendFormat(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700521 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700522 l.compositionType ? "OVERLAY" : "FB",
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700523 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
Mathias Agopian83727852010-09-23 18:13:21 -0700524 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
Mathias Agopian22da60c2011-09-09 00:49:11 -0700525 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700526 layer->getName().string());
Mathias Agopian83727852010-09-23 18:13:21 -0700527 }
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800528 }
Mathias Agopian30bcc612012-08-22 15:39:48 -0700529
530 if (mHwc && mHwc->dump) {
531 mHwc->dump(mHwc, buffer, SIZE);
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800532 result.append(buffer);
Mathias Agopian83727852010-09-23 18:13:21 -0700533 }
534}
535
Mathias Agopiana350ff92010-08-10 17:14:02 -0700536// ---------------------------------------------------------------------------
Mathias Agopian2965b262012-04-08 15:13:32 -0700537
538HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
539 : mHwc(hwc), mEnabled(false),
540 mNextFakeVSync(0),
Mathias Agopiane60b0682012-08-21 23:34:09 -0700541 mRefreshPeriod(hwc.getRefreshPeriod())
Mathias Agopian2965b262012-04-08 15:13:32 -0700542{
543}
544
545void HWComposer::VSyncThread::setEnabled(bool enabled) {
546 Mutex::Autolock _l(mLock);
547 mEnabled = enabled;
548 mCondition.signal();
549}
550
551void HWComposer::VSyncThread::onFirstRef() {
552 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
553}
554
555bool HWComposer::VSyncThread::threadLoop() {
556 { // scope for lock
557 Mutex::Autolock _l(mLock);
558 while (!mEnabled) {
559 mCondition.wait(mLock);
560 }
561 }
562
563 const nsecs_t period = mRefreshPeriod;
564 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
565 nsecs_t next_vsync = mNextFakeVSync;
566 nsecs_t sleep = next_vsync - now;
567 if (sleep < 0) {
568 // we missed, find where the next vsync should be
569 sleep = (period - ((now - next_vsync) % period));
570 next_vsync = now + sleep;
571 }
572 mNextFakeVSync = next_vsync + period;
573
574 struct timespec spec;
575 spec.tv_sec = next_vsync / 1000000000;
576 spec.tv_nsec = next_vsync % 1000000000;
577
578 int err;
579 do {
580 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
581 } while (err<0 && errno == EINTR);
582
583 if (err == 0) {
584 mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
585 }
586
587 return true;
588}
589
590// ---------------------------------------------------------------------------
Mathias Agopiana350ff92010-08-10 17:14:02 -0700591}; // namespace android