blob: 403b9799bbff46e54997e485a7e2f4c5cfbcc8f6 [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
20// #define HWC_REMOVE_DEPRECATED_VERSIONS 1
21
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
49// ---------------------------------------------------------------------------
50// Support for HWC_DEVICE_API_VERSION_0_3 and older:
51// Since v0.3 is deprecated and support will be dropped soon, as much as
52// possible the code is written to target v1.0. When using a v0.3 HWC, we
Jesse Hallb685c542012-07-31 14:32:56 -070053// allocate v0.3 structures, but assign them to v1.0 pointers.
Jesse Hall5880cc52012-06-05 23:40:32 -070054
55#if HWC_REMOVE_DEPRECATED_VERSIONS
Jesse Hallb685c542012-07-31 14:32:56 -070056// We need complete types to satisfy semantic checks, even though the code
57// paths that use these won't get executed at runtime (and will likely be dead-
58// code-eliminated). When we remove the code to support v0.3 we can remove
Jesse Hall5880cc52012-06-05 23:40:32 -070059// these as well.
60typedef hwc_layer_1_t hwc_layer_t;
Jesse Hallb685c542012-07-31 14:32:56 -070061typedef hwc_display_contents_1_t hwc_layer_list_t;
Jesse Hall5880cc52012-06-05 23:40:32 -070062typedef hwc_composer_device_1_t hwc_composer_device_t;
63#endif
64
65// This function assumes we've already rejected HWC's with lower-than-required
66// versions. Don't use it for the initial "does HWC meet requirements" check!
67static bool hwcHasVersion(const hwc_composer_device_1_t* hwc, uint32_t version) {
68 if (HWC_REMOVE_DEPRECATED_VERSIONS &&
69 version <= HWC_DEVICE_API_VERSION_1_0) {
70 return true;
71 } else {
72 return hwc->common.version >= version;
73 }
74}
75
Jesse Hallb685c542012-07-31 14:32:56 -070076static bool hwcHasVsyncEvent(const hwc_composer_device_1_t* hwc) {
77 return hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_0_3);
78}
79
Jesse Hall5880cc52012-06-05 23:40:32 -070080static size_t sizeofHwcLayerList(const hwc_composer_device_1_t* hwc,
81 size_t numLayers) {
82 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
Jesse Hallb685c542012-07-31 14:32:56 -070083 return sizeof(hwc_display_contents_1_t) + numLayers*sizeof(hwc_layer_1_t);
Jesse Hall5880cc52012-06-05 23:40:32 -070084 } else {
85 return sizeof(hwc_layer_list_t) + numLayers*sizeof(hwc_layer_t);
86 }
87}
88
Jesse Hallb685c542012-07-31 14:32:56 -070089static int hwcEventControl(hwc_composer_device_1_t* hwc, int dpy,
90 int event, int enabled) {
91 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
Jesse Hallbbd164a2012-08-21 12:05:09 -070092 return hwc->eventControl(hwc, dpy, event, enabled);
Jesse Hallb685c542012-07-31 14:32:56 -070093 } else {
Mathias Agopian1e260872012-08-08 18:35:12 -070094 hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
Jesse Hallb685c542012-07-31 14:32:56 -070095 return hwc0->methods->eventControl(hwc0, event, enabled);
96 }
97}
98
99static int hwcBlank(hwc_composer_device_1_t* hwc, int dpy, int blank) {
100 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
Jesse Hallbbd164a2012-08-21 12:05:09 -0700101 return hwc->blank(hwc, dpy, blank);
Jesse Hallb685c542012-07-31 14:32:56 -0700102 } else {
103 if (blank) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700104 hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
Jesse Hallb685c542012-07-31 14:32:56 -0700105 return hwc0->set(hwc0, NULL, NULL, NULL);
106 } else {
107 // HWC 0.x turns the screen on at the next set()
108 return NO_ERROR;
109 }
110 }
111}
112
113static int hwcPrepare(hwc_composer_device_1_t* hwc,
114 size_t numDisplays, hwc_display_contents_1_t** displays) {
115 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
116 return hwc->prepare(hwc, numDisplays, displays);
117 } else {
Mathias Agopian1e260872012-08-08 18:35:12 -0700118 hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
119 hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(displays[0]);
Jesse Hallb685c542012-07-31 14:32:56 -0700120 // In the past, SurfaceFlinger would pass a NULL list when doing full
121 // OpenGL ES composition. I don't know what, if any, dependencies there
122 // are on this behavior, so I'm playing it safe and preserving it.
123 if (list0->numHwLayers == 0)
124 return hwc0->prepare(hwc0, NULL);
125 else
126 return hwc0->prepare(hwc0, list0);
127 }
128}
129
130static int hwcSet(hwc_composer_device_1_t* hwc, EGLDisplay dpy, EGLSurface sur,
131 size_t numDisplays, hwc_display_contents_1_t** displays) {
132 int err;
133 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
134 displays[0]->dpy = dpy;
135 displays[0]->sur = sur;
136 err = hwc->set(hwc, numDisplays, displays);
137 } else {
Mathias Agopian1e260872012-08-08 18:35:12 -0700138 hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
139 hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(displays[0]);
Jesse Hallb685c542012-07-31 14:32:56 -0700140 err = hwc0->set(hwc0, dpy, sur, list0);
141 }
142 return err;
143}
144
145static uint32_t& hwcFlags(hwc_composer_device_1_t* hwc,
146 hwc_display_contents_1_t* display) {
147 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
148 return display->flags;
149 } else {
Mathias Agopian1e260872012-08-08 18:35:12 -0700150 hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(display);
Jesse Hallb685c542012-07-31 14:32:56 -0700151 return list0->flags;
152 }
153}
154
155static size_t& hwcNumHwLayers(hwc_composer_device_1_t* hwc,
156 hwc_display_contents_1_t* display) {
157 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
158 return display->numHwLayers;
159 } else {
Mathias Agopian1e260872012-08-08 18:35:12 -0700160 hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(display);
Jesse Hallb685c542012-07-31 14:32:56 -0700161 return list0->numHwLayers;
162 }
163}
164
Jesse Hallbbd164a2012-08-21 12:05:09 -0700165static void hwcDump(hwc_composer_device_1_t* hwc, char* buff, int buff_len) {
166 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
167 if (hwc->dump)
168 hwc->dump(hwc, buff, buff_len);
169 } else if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_0_1)) {
170 hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
171 if (hwc0->dump)
172 hwc0->dump(hwc0, buff, buff_len);
173 }
174}
175
Mathias Agopiana350ff92010-08-10 17:14:02 -0700176// ---------------------------------------------------------------------------
177
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700178struct HWComposer::cb_context {
179 struct callbacks : public hwc_procs_t {
180 // these are here to facilitate the transition when adding
181 // new callbacks (an implementation can check for NULL before
182 // calling a new callback).
183 void (*zero[4])(void);
184 };
185 callbacks procs;
186 HWComposer* hwc;
187};
188
189// ---------------------------------------------------------------------------
190
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700191HWComposer::HWComposer(
192 const sp<SurfaceFlinger>& flinger,
Mathias Agopian8b736f12012-08-13 17:54:26 -0700193 EventHandler& handler,
194 framebuffer_device_t const* fbDev)
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700195 : mFlinger(flinger),
Jesse Hall8f971ff2012-08-22 11:50:00 -0700196 mModule(0), mHwc(0), mNumDisplays(1), mCapacity(0),
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700197 mNumOVLayers(0), mNumFBLayers(0),
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700198 mCBContext(new cb_context),
Mathias Agopian888c8222012-08-04 21:10:38 -0700199 mEventHandler(handler), mRefreshPeriod(0),
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700200 mVSyncCount(0), mDebugForceFakeVSync(false)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700201{
Jesse Hallb685c542012-07-31 14:32:56 -0700202 for (size_t i = 0; i < MAX_DISPLAYS; i++)
203 mLists[i] = NULL;
204
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700205 char value[PROPERTY_VALUE_MAX];
206 property_get("debug.sf.no_hw_vsync", value, "0");
207 mDebugForceFakeVSync = atoi(value);
208
Mathias Agopian028508c2012-07-25 21:12:12 -0700209 bool needVSyncThread = true;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700210 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
Steve Block32397c12012-01-05 23:22:43 +0000211 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700212 if (err == 0) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700213 err = hwc_open_1(mModule, &mHwc);
Steve Blocke6f43dd2012-01-06 19:20:56 +0000214 ALOGE_IF(err, "%s device failed to initialize (%s)",
Mathias Agopiana350ff92010-08-10 17:14:02 -0700215 HWC_HARDWARE_COMPOSER, strerror(-err));
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700216 if (err == 0) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700217 if (HWC_REMOVE_DEPRECATED_VERSIONS &&
218 mHwc->common.version < HWC_DEVICE_API_VERSION_1_0) {
219 ALOGE("%s device version %#x too old, will not be used",
220 HWC_HARDWARE_COMPOSER, mHwc->common.version);
221 hwc_close_1(mHwc);
222 mHwc = NULL;
223 }
224 }
225
226 if (mHwc) {
Jesse Hallbbd164a2012-08-21 12:05:09 -0700227 if (mHwc->registerProcs) {
228 mCBContext->hwc = this;
229 mCBContext->procs.invalidate = &hook_invalidate;
230 mCBContext->procs.vsync = &hook_vsync;
231 memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
232 mHwc->registerProcs(mHwc, &mCBContext->procs);
233 }
234
Jesse Hallb685c542012-07-31 14:32:56 -0700235 // always turn vsync off when we start
236 needVSyncThread = false;
237 if (hwcHasVsyncEvent(mHwc)) {
238 hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
Mathias Agopian888c8222012-08-04 21:10:38 -0700239
240 int period;
241 if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) {
242 mRefreshPeriod = nsecs_t(period);
243 }
Jesse Hallb685c542012-07-31 14:32:56 -0700244 } else {
245 needVSyncThread = true;
Mathias Agopian028508c2012-07-25 21:12:12 -0700246 }
Jesse Hallb685c542012-07-31 14:32:56 -0700247
Jesse Hall8f971ff2012-08-22 11:50:00 -0700248 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
249 mNumDisplays = HWC_NUM_DISPLAY_TYPES;
250
Jesse Hallb685c542012-07-31 14:32:56 -0700251 // create initial empty display contents for display 0
Jesse Hall8f971ff2012-08-22 11:50:00 -0700252 createWorkList(HWC_DISPLAY_PRIMARY, 0);
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700253 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700254 }
255
Mathias Agopian8b736f12012-08-13 17:54:26 -0700256
257 if (fbDev) {
258 if (mRefreshPeriod == 0) {
259 mRefreshPeriod = nsecs_t(1e9 / fbDev->fps);
260 ALOGW("getting VSYNC period from fb HAL: %lld", mRefreshPeriod);
Mathias Agopian888c8222012-08-04 21:10:38 -0700261 }
Mathias Agopian8b736f12012-08-13 17:54:26 -0700262 mDpiX = fbDev->xdpi;
263 mDpiY = fbDev->ydpi;
Mathias Agopian888c8222012-08-04 21:10:38 -0700264 }
265
266 if (mRefreshPeriod == 0) {
267 mRefreshPeriod = nsecs_t(1e9 / 60.0);
268 ALOGW("getting VSYNC period thin air: %lld", mRefreshPeriod);
269 }
270
Mathias Agopian3a778712012-04-09 14:16:47 -0700271 if (needVSyncThread) {
272 // we don't have VSYNC support, we need to fake it
273 mVSyncThread = new VSyncThread(*this);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700274 }
275}
276
277HWComposer::~HWComposer() {
Jesse Hallb685c542012-07-31 14:32:56 -0700278 hwcEventControl(mHwc, 0, EVENT_VSYNC, 0);
279 for (size_t i = 0; i < MAX_DISPLAYS; i++)
280 free(mLists[i]);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700281 if (mVSyncThread != NULL) {
282 mVSyncThread->requestExitAndWait();
283 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700284 if (mHwc) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700285 hwc_close_1(mHwc);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700286 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700287 delete mCBContext;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700288}
289
290status_t HWComposer::initCheck() const {
291 return mHwc ? NO_ERROR : NO_INIT;
292}
293
Jesse Hallbbd164a2012-08-21 12:05:09 -0700294void HWComposer::hook_invalidate(const struct hwc_procs* procs) {
295 cb_context* ctx = reinterpret_cast<cb_context*>(
296 const_cast<hwc_procs_t*>(procs));
297 ctx->hwc->invalidate();
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700298}
299
Jesse Hallbbd164a2012-08-21 12:05:09 -0700300void HWComposer::hook_vsync(const struct hwc_procs* procs, int dpy,
301 int64_t timestamp) {
302 cb_context* ctx = reinterpret_cast<cb_context*>(
303 const_cast<hwc_procs_t*>(procs));
304 ctx->hwc->vsync(dpy, timestamp);
Mathias Agopian31d28432012-04-03 16:31:39 -0700305}
306
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700307void HWComposer::invalidate() {
Mathias Agopiane2c2f922011-10-05 15:00:22 -0700308 mFlinger->repaintEverything();
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700309}
310
Mathias Agopian31d28432012-04-03 16:31:39 -0700311void HWComposer::vsync(int dpy, int64_t timestamp) {
Mathias Agopian2965b262012-04-08 15:13:32 -0700312 ATRACE_INT("VSYNC", ++mVSyncCount&1);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700313 mEventHandler.onVSyncReceived(dpy, timestamp);
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700314 Mutex::Autolock _l(mLock);
315 mLastHwVSync = timestamp;
316}
317
Mathias Agopian888c8222012-08-04 21:10:38 -0700318nsecs_t HWComposer::getRefreshPeriod() const {
319 return mRefreshPeriod;
320}
321
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700322nsecs_t HWComposer::getRefreshTimestamp() const {
323 // this returns the last refresh timestamp.
324 // if the last one is not available, we estimate it based on
325 // the refresh period and whatever closest timestamp we have.
326 Mutex::Autolock _l(mLock);
327 nsecs_t now = systemTime(CLOCK_MONOTONIC);
328 return now - ((now - mLastHwVSync) % mRefreshPeriod);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700329}
330
Mathias Agopian8b736f12012-08-13 17:54:26 -0700331float HWComposer::getDpiX() const {
332 return mDpiX;
333}
334
335float HWComposer::getDpiY() const {
336 return mDpiY;
337}
338
Mathias Agopian03e40722012-04-26 16:11:59 -0700339void HWComposer::eventControl(int event, int enabled) {
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700340 status_t err = NO_ERROR;
Erik Gilling1a3bf412012-04-06 14:13:32 -0700341 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700342 if (!mDebugForceFakeVSync) {
Jesse Hallb685c542012-07-31 14:32:56 -0700343 err = hwcEventControl(mHwc, 0, event, enabled);
Mathias Agopian03e40722012-04-26 16:11:59 -0700344 // error here should not happen -- not sure what we should
345 // do if it does.
346 ALOGE_IF(err, "eventControl(%d, %d) failed %s",
347 event, enabled, strerror(-err));
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700348 }
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700349 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700350
351 if (err == NO_ERROR && mVSyncThread != NULL) {
352 mVSyncThread->setEnabled(enabled);
353 }
Mathias Agopian31d28432012-04-03 16:31:39 -0700354}
355
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700356status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
357 // FIXME: handle multiple displays
Mathias Agopian1e260872012-08-08 18:35:12 -0700358 if (uint32_t(id) >= MAX_DISPLAYS)
359 return BAD_INDEX;
360
Mathias Agopian45721772010-08-12 15:03:26 -0700361 if (mHwc) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700362 // TODO: must handle multiple displays here
Jesse Hallb685c542012-07-31 14:32:56 -0700363 // mLists[0] is NULL only when this is called from the constructor
364 if (!mLists[0] || mCapacity < numLayers) {
365 free(mLists[0]);
Jesse Hall5880cc52012-06-05 23:40:32 -0700366 size_t size = sizeofHwcLayerList(mHwc, numLayers);
Jesse Hallb685c542012-07-31 14:32:56 -0700367 mLists[0] = (hwc_display_contents_1_t*)malloc(size);
Mathias Agopian45721772010-08-12 15:03:26 -0700368 mCapacity = numLayers;
369 }
Jesse Hallb685c542012-07-31 14:32:56 -0700370 hwcFlags(mHwc, mLists[0]) = HWC_GEOMETRY_CHANGED;
371 hwcNumHwLayers(mHwc, mLists[0]) = numLayers;
372 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
373 mLists[0]->flipFenceFd = -1;
374 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700375 }
376 return NO_ERROR;
377}
378
379status_t HWComposer::prepare() const {
Jesse Hall8f971ff2012-08-22 11:50:00 -0700380 int err = hwcPrepare(mHwc, mNumDisplays,
Jesse Hallb685c542012-07-31 14:32:56 -0700381 const_cast<hwc_display_contents_1_t**>(mLists));
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700382 if (err == NO_ERROR) {
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700383
384 // here we're just making sure that "skip" layers are set
385 // to HWC_FRAMEBUFFER and we're also counting how many layers
386 // we have of each type.
387 // It would be nice if we could get rid of this entirely, which I
388 // think is almost possible.
389
390 // TODO: must handle multiple displays here
391
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700392 size_t numOVLayers = 0;
393 size_t numFBLayers = 0;
Mathias Agopian1e260872012-08-08 18:35:12 -0700394 size_t count = getNumLayers(0);
395
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700396 for (size_t i=0 ; i<count ; i++) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700397 int compositionType;
Jesse Hall5880cc52012-06-05 23:40:32 -0700398 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700399 hwc_layer_1_t* l = &mLists[0]->hwLayers[i];
400 if (l->flags & HWC_SKIP_LAYER) {
401 l->compositionType = HWC_FRAMEBUFFER;
402 }
403 compositionType = l->compositionType;
Jesse Hall5880cc52012-06-05 23:40:32 -0700404 } else {
405 // mList really has hwc_layer_list_t memory layout
Mathias Agopian1e260872012-08-08 18:35:12 -0700406 hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
407 hwc_layer_t* l = &list0->hwLayers[i];
408 if (l->flags & HWC_SKIP_LAYER) {
409 l->compositionType = HWC_FRAMEBUFFER;
410 }
411 compositionType = l->compositionType;
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700412 }
Mathias Agopian1e260872012-08-08 18:35:12 -0700413
414 switch (compositionType) {
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700415 case HWC_OVERLAY:
416 numOVLayers++;
417 break;
418 case HWC_FRAMEBUFFER:
419 numFBLayers++;
420 break;
421 }
422 }
423 mNumOVLayers = numOVLayers;
424 mNumFBLayers = numFBLayers;
425 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700426 return (status_t)err;
427}
428
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700429size_t HWComposer::getLayerCount(int32_t id, int type) const {
430 // FIXME: handle multiple displays
431 if (uint32_t(id) >= MAX_DISPLAYS) {
432 // FIXME: in practice this is only use to know
433 // if we have at least one layer of type.
434 return (type == HWC_FRAMEBUFFER) ? 1 : 0;
435 }
436
437
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700438 switch (type) {
439 case HWC_OVERLAY:
440 return mNumOVLayers;
441 case HWC_FRAMEBUFFER:
442 return mNumFBLayers;
443 }
444 return 0;
445}
446
Jesse Hall34a09ba2012-07-29 22:35:34 -0700447status_t HWComposer::commit(void* fbDisplay, void* fbSurface) const {
Mathias Agopian86303202012-07-24 22:46:10 -0700448 int err = NO_ERROR;
449 if (mHwc) {
Jesse Hall8f971ff2012-08-22 11:50:00 -0700450 err = hwcSet(mHwc, fbDisplay, fbSurface, mNumDisplays,
Jesse Hallb685c542012-07-31 14:32:56 -0700451 const_cast<hwc_display_contents_1_t**>(mLists));
452 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
453 if (mLists[0]->flipFenceFd != -1) {
454 close(mLists[0]->flipFenceFd);
455 mLists[0]->flipFenceFd = -1;
456 }
Mathias Agopian86303202012-07-24 22:46:10 -0700457 }
Jesse Hallb685c542012-07-31 14:32:56 -0700458 hwcFlags(mHwc, mLists[0]) &= ~HWC_GEOMETRY_CHANGED;
Mathias Agopian58959342010-10-07 14:57:04 -0700459 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700460 return (status_t)err;
461}
462
Antti Hatalaf5f27122010-09-09 02:33:05 -0700463status_t HWComposer::release() const {
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700464 if (mHwc) {
Jesse Hallb685c542012-07-31 14:32:56 -0700465 if (hwcHasVsyncEvent(mHwc)) {
466 hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
Mathias Agopian22ffb112012-04-10 21:04:02 -0700467 }
Jesse Hallb685c542012-07-31 14:32:56 -0700468 return (status_t)hwcBlank(mHwc, 0, 1);
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700469 }
470 return NO_ERROR;
471}
472
Colin Cross10fbdb62012-07-12 17:56:34 -0700473status_t HWComposer::acquire() const {
474 if (mHwc) {
Jesse Hallb685c542012-07-31 14:32:56 -0700475 return (status_t)hwcBlank(mHwc, 0, 0);
Colin Cross10fbdb62012-07-12 17:56:34 -0700476 }
Colin Cross10fbdb62012-07-12 17:56:34 -0700477 return NO_ERROR;
478}
479
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700480status_t HWComposer::disable() {
481 if (mHwc) {
Jesse Hallb685c542012-07-31 14:32:56 -0700482 hwcNumHwLayers(mHwc, mLists[0]) = 0;
Jesse Hall8f971ff2012-08-22 11:50:00 -0700483 int err = hwcPrepare(mHwc, mNumDisplays, mLists);
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700484 return (status_t)err;
485 }
486 return NO_ERROR;
Antti Hatalaf5f27122010-09-09 02:33:05 -0700487}
488
Mathias Agopian1e260872012-08-08 18:35:12 -0700489size_t HWComposer::getNumLayers(int32_t id) const { // FIXME: handle multiple displays
Jesse Hallb685c542012-07-31 14:32:56 -0700490 return mHwc ? hwcNumHwLayers(mHwc, mLists[0]) : 0;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700491}
492
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700493/*
494 * Helper template to implement a concrete HWCLayer
495 * This holds the pointer to the concrete hwc layer type
496 * and implements the "iterable" side of HWCLayer.
497 */
498template<typename CONCRETE, typename HWCTYPE>
499class Iterable : public HWComposer::HWCLayer {
500protected:
501 HWCTYPE* const mLayerList;
502 HWCTYPE* mCurrentLayer;
503 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
504 inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
505 inline HWCTYPE* getLayer() { return mCurrentLayer; }
506 virtual ~Iterable() { }
507private:
508 // returns a copy of ourselves
509 virtual HWComposer::HWCLayer* dup() {
510 return new CONCRETE( static_cast<const CONCRETE&>(*this) );
511 }
512 virtual status_t setLayer(size_t index) {
513 mCurrentLayer = &mLayerList[index];
514 return NO_ERROR;
515 }
516};
517
Jesse Hall5880cc52012-06-05 23:40:32 -0700518// #if !HWC_REMOVE_DEPRECATED_VERSIONS
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700519/*
520 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
521 * This implements the HWCLayer side of HWCIterableLayer.
522 */
Jesse Hall5880cc52012-06-05 23:40:32 -0700523class HWCLayerVersion0 : public Iterable<HWCLayerVersion0, hwc_layer_t> {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700524public:
Jesse Hall5880cc52012-06-05 23:40:32 -0700525 HWCLayerVersion0(hwc_layer_t* layer)
526 : Iterable<HWCLayerVersion0, hwc_layer_t>(layer) { }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700527
528 virtual int32_t getCompositionType() const {
529 return getLayer()->compositionType;
530 }
531 virtual uint32_t getHints() const {
532 return getLayer()->hints;
533 }
Jesse Hallef194142012-06-14 14:45:17 -0700534 virtual int getAndResetReleaseFenceFd() {
535 // not supported on VERSION_03
536 return -1;
537 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700538 virtual void setAcquireFenceFd(int fenceFd) {
539 if (fenceFd != -1) {
540 ALOGE("HWC 0.x can't handle acquire fences");
541 close(fenceFd);
542 }
543 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700544
545 virtual void setDefaultState() {
546 getLayer()->compositionType = HWC_FRAMEBUFFER;
547 getLayer()->hints = 0;
548 getLayer()->flags = HWC_SKIP_LAYER;
549 getLayer()->transform = 0;
550 getLayer()->blending = HWC_BLENDING_NONE;
551 getLayer()->visibleRegionScreen.numRects = 0;
552 getLayer()->visibleRegionScreen.rects = NULL;
553 }
554 virtual void setSkip(bool skip) {
555 if (skip) {
556 getLayer()->flags |= HWC_SKIP_LAYER;
557 } else {
558 getLayer()->flags &= ~HWC_SKIP_LAYER;
559 }
560 }
561 virtual void setBlending(uint32_t blending) {
562 getLayer()->blending = blending;
563 }
564 virtual void setTransform(uint32_t transform) {
565 getLayer()->transform = transform;
566 }
567 virtual void setFrame(const Rect& frame) {
568 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
569 }
570 virtual void setCrop(const Rect& crop) {
571 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
572 }
573 virtual void setVisibleRegionScreen(const Region& reg) {
574 getLayer()->visibleRegionScreen.rects =
575 reinterpret_cast<hwc_rect_t const *>(
576 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
577 }
578 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
579 if (buffer == 0 || buffer->handle == 0) {
580 getLayer()->compositionType = HWC_FRAMEBUFFER;
581 getLayer()->flags |= HWC_SKIP_LAYER;
582 getLayer()->handle = 0;
583 } else {
584 getLayer()->handle = buffer->handle;
585 }
586 }
587};
Jesse Hall5880cc52012-06-05 23:40:32 -0700588// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS
589
590/*
591 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
592 * This implements the HWCLayer side of HWCIterableLayer.
593 */
594class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> {
595public:
596 HWCLayerVersion1(hwc_layer_1_t* layer)
597 : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer) { }
598
599 virtual int32_t getCompositionType() const {
600 return getLayer()->compositionType;
601 }
602 virtual uint32_t getHints() const {
603 return getLayer()->hints;
604 }
Jesse Hallef194142012-06-14 14:45:17 -0700605 virtual int getAndResetReleaseFenceFd() {
606 int fd = getLayer()->releaseFenceFd;
607 getLayer()->releaseFenceFd = -1;
608 return fd;
609 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700610 virtual void setAcquireFenceFd(int fenceFd) {
611 getLayer()->acquireFenceFd = fenceFd;
612 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700613
614 virtual void setDefaultState() {
615 getLayer()->compositionType = HWC_FRAMEBUFFER;
616 getLayer()->hints = 0;
617 getLayer()->flags = HWC_SKIP_LAYER;
618 getLayer()->transform = 0;
619 getLayer()->blending = HWC_BLENDING_NONE;
620 getLayer()->visibleRegionScreen.numRects = 0;
621 getLayer()->visibleRegionScreen.rects = NULL;
622 getLayer()->acquireFenceFd = -1;
623 getLayer()->releaseFenceFd = -1;
624 }
625 virtual void setSkip(bool skip) {
626 if (skip) {
627 getLayer()->flags |= HWC_SKIP_LAYER;
628 } else {
629 getLayer()->flags &= ~HWC_SKIP_LAYER;
630 }
631 }
632 virtual void setBlending(uint32_t blending) {
633 getLayer()->blending = blending;
634 }
635 virtual void setTransform(uint32_t transform) {
636 getLayer()->transform = transform;
637 }
638 virtual void setFrame(const Rect& frame) {
639 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
640 }
641 virtual void setCrop(const Rect& crop) {
642 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
643 }
644 virtual void setVisibleRegionScreen(const Region& reg) {
645 getLayer()->visibleRegionScreen.rects =
646 reinterpret_cast<hwc_rect_t const *>(
647 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
648 }
649 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
650 if (buffer == 0 || buffer->handle == 0) {
651 getLayer()->compositionType = HWC_FRAMEBUFFER;
652 getLayer()->flags |= HWC_SKIP_LAYER;
653 getLayer()->handle = 0;
654 } else {
655 getLayer()->handle = buffer->handle;
656 }
657 }
658};
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700659
660/*
661 * returns an iterator initialized at a given index in the layer list
662 */
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700663HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) {
664 // FIXME: handle multiple displays
665 if (uint32_t(id) >= MAX_DISPLAYS)
666 return LayerListIterator();
667
Mathias Agopian748f3df2012-08-10 14:36:40 -0700668 if (!mHwc || index > hwcNumHwLayers(mHwc, mLists[0]))
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700669 return LayerListIterator();
Jesse Hall5880cc52012-06-05 23:40:32 -0700670 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
Jesse Hallb685c542012-07-31 14:32:56 -0700671 return LayerListIterator(new HWCLayerVersion1(mLists[0]->hwLayers),
672 index);
Jesse Hall5880cc52012-06-05 23:40:32 -0700673 } else {
Mathias Agopian1e260872012-08-08 18:35:12 -0700674 hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
Jesse Hall5880cc52012-06-05 23:40:32 -0700675 return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index);
676 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700677}
678
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700679/*
680 * returns an iterator on the beginning of the layer list
681 */
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700682HWComposer::LayerListIterator HWComposer::begin(int32_t id) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700683 return getLayerIterator(id, 0);
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700684}
685
686/*
687 * returns an iterator on the end of the layer list
688 */
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700689HWComposer::LayerListIterator HWComposer::end(int32_t id) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700690 return getLayerIterator(id, getNumLayers(id));
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700691}
692
Mathias Agopian22da60c2011-09-09 00:49:11 -0700693void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
694 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
Jesse Hallb685c542012-07-31 14:32:56 -0700695 if (mHwc) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700696 hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
Jesse Hallb685c542012-07-31 14:32:56 -0700697
Mathias Agopian83727852010-09-23 18:13:21 -0700698 result.append("Hardware Composer state:\n");
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700699 result.appendFormat(" mDebugForceFakeVSync=%d\n",
700 mDebugForceFakeVSync);
701 result.appendFormat(" numHwLayers=%u, flags=%08x\n",
Jesse Hallb685c542012-07-31 14:32:56 -0700702 hwcNumHwLayers(mHwc, mLists[0]), hwcFlags(mHwc, mLists[0]));
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700703 result.append(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700704 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n"
705 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
706 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
Jesse Hallb685c542012-07-31 14:32:56 -0700707 for (size_t i=0 ; i<hwcNumHwLayers(mHwc, mLists[0]) ; i++) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700708 hwc_layer_1_t const* lp;
Jesse Hall5880cc52012-06-05 23:40:32 -0700709 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
Mathias Agopian1e260872012-08-08 18:35:12 -0700710 lp = &mLists[0]->hwLayers[i];
Jesse Hall5880cc52012-06-05 23:40:32 -0700711 } else {
Mathias Agopian1e260872012-08-08 18:35:12 -0700712 // FIXME: here we rely on hwc_layer_1_t and hwc_layer_t having the same layout
713 lp = reinterpret_cast<hwc_layer_1_t const*>(&list0->hwLayers[i]);
Jesse Hall5880cc52012-06-05 23:40:32 -0700714 }
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700715 const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
716 int32_t format = -1;
717 if (layer->getLayer() != NULL) {
718 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
719 if (buffer != NULL) {
720 format = buffer->getPixelFormat();
721 }
722 }
Mathias Agopian1e260872012-08-08 18:35:12 -0700723 const hwc_layer_1_t& l(*lp);
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700724 result.appendFormat(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700725 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700726 l.compositionType ? "OVERLAY" : "FB",
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700727 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
Mathias Agopian83727852010-09-23 18:13:21 -0700728 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
Mathias Agopian22da60c2011-09-09 00:49:11 -0700729 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700730 layer->getName().string());
Mathias Agopian83727852010-09-23 18:13:21 -0700731 }
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800732 }
Jesse Hallbbd164a2012-08-21 12:05:09 -0700733 if (mHwc) {
734 hwcDump(mHwc, buffer, SIZE);
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800735 result.append(buffer);
Mathias Agopian83727852010-09-23 18:13:21 -0700736 }
737}
738
Mathias Agopiana350ff92010-08-10 17:14:02 -0700739// ---------------------------------------------------------------------------
Mathias Agopian2965b262012-04-08 15:13:32 -0700740
741HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
742 : mHwc(hwc), mEnabled(false),
743 mNextFakeVSync(0),
744 mRefreshPeriod(hwc.mRefreshPeriod)
745{
746}
747
748void HWComposer::VSyncThread::setEnabled(bool enabled) {
749 Mutex::Autolock _l(mLock);
750 mEnabled = enabled;
751 mCondition.signal();
752}
753
754void HWComposer::VSyncThread::onFirstRef() {
755 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
756}
757
758bool HWComposer::VSyncThread::threadLoop() {
759 { // scope for lock
760 Mutex::Autolock _l(mLock);
761 while (!mEnabled) {
762 mCondition.wait(mLock);
763 }
764 }
765
766 const nsecs_t period = mRefreshPeriod;
767 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
768 nsecs_t next_vsync = mNextFakeVSync;
769 nsecs_t sleep = next_vsync - now;
770 if (sleep < 0) {
771 // we missed, find where the next vsync should be
772 sleep = (period - ((now - next_vsync) % period));
773 next_vsync = now + sleep;
774 }
775 mNextFakeVSync = next_vsync + period;
776
777 struct timespec spec;
778 spec.tv_sec = next_vsync / 1000000000;
779 spec.tv_nsec = next_vsync % 1000000000;
780
781 int err;
782 do {
783 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
784 } while (err<0 && errno == EINTR);
785
786 if (err == 0) {
787 mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
788 }
789
790 return true;
791}
792
793// ---------------------------------------------------------------------------
Mathias Agopiana350ff92010-08-10 17:14:02 -0700794}; // namespace android