blob: 40ce90b9aa6d877a3edbec09c020cb122a901035 [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)) {
92 return hwc->methods->eventControl(hwc, dpy, event, enabled);
93 } else {
94 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
95 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)) {
101 return hwc->methods->blank(hwc, dpy, blank);
102 } else {
103 if (blank) {
104 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
105 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 {
118 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
119 hwc_layer_list_t* list0 = (hwc_layer_list_t*)displays[0];
120 // 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 {
138 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
139 hwc_layer_list_t* list0 = (hwc_layer_list_t*)displays[0];
140 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 {
150 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
151 hwc_layer_list_t* list0 = (hwc_layer_list_t*)display;
152 return list0->flags;
153 }
154}
155
156static size_t& hwcNumHwLayers(hwc_composer_device_1_t* hwc,
157 hwc_display_contents_1_t* display) {
158 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
159 return display->numHwLayers;
160 } else {
161 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
162 hwc_layer_list_t* list0 = (hwc_layer_list_t*)display;
163 return list0->numHwLayers;
164 }
165}
166
Mathias Agopiana350ff92010-08-10 17:14:02 -0700167// ---------------------------------------------------------------------------
168
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700169struct HWComposer::cb_context {
170 struct callbacks : public hwc_procs_t {
171 // these are here to facilitate the transition when adding
172 // new callbacks (an implementation can check for NULL before
173 // calling a new callback).
174 void (*zero[4])(void);
175 };
176 callbacks procs;
177 HWComposer* hwc;
178};
179
180// ---------------------------------------------------------------------------
181
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700182HWComposer::HWComposer(
183 const sp<SurfaceFlinger>& flinger,
Mathias Agopian888c8222012-08-04 21:10:38 -0700184 EventHandler& handler)
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700185 : mFlinger(flinger),
Jesse Hallb685c542012-07-31 14:32:56 -0700186 mModule(0), mHwc(0), mCapacity(0),
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700187 mNumOVLayers(0), mNumFBLayers(0),
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700188 mCBContext(new cb_context),
Mathias Agopian888c8222012-08-04 21:10:38 -0700189 mEventHandler(handler), mRefreshPeriod(0),
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700190 mVSyncCount(0), mDebugForceFakeVSync(false)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700191{
Jesse Hallb685c542012-07-31 14:32:56 -0700192 for (size_t i = 0; i < MAX_DISPLAYS; i++)
193 mLists[i] = NULL;
194
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700195 char value[PROPERTY_VALUE_MAX];
196 property_get("debug.sf.no_hw_vsync", value, "0");
197 mDebugForceFakeVSync = atoi(value);
198
Mathias Agopian028508c2012-07-25 21:12:12 -0700199 bool needVSyncThread = true;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700200 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
Steve Block32397c12012-01-05 23:22:43 +0000201 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700202 if (err == 0) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700203 err = hwc_open_1(mModule, &mHwc);
Steve Blocke6f43dd2012-01-06 19:20:56 +0000204 ALOGE_IF(err, "%s device failed to initialize (%s)",
Mathias Agopiana350ff92010-08-10 17:14:02 -0700205 HWC_HARDWARE_COMPOSER, strerror(-err));
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700206 if (err == 0) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700207 if (HWC_REMOVE_DEPRECATED_VERSIONS &&
208 mHwc->common.version < HWC_DEVICE_API_VERSION_1_0) {
209 ALOGE("%s device version %#x too old, will not be used",
210 HWC_HARDWARE_COMPOSER, mHwc->common.version);
211 hwc_close_1(mHwc);
212 mHwc = NULL;
213 }
214 }
215
216 if (mHwc) {
Jesse Hallb685c542012-07-31 14:32:56 -0700217 // always turn vsync off when we start
218 needVSyncThread = false;
219 if (hwcHasVsyncEvent(mHwc)) {
220 hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
Mathias Agopian888c8222012-08-04 21:10:38 -0700221
222 int period;
223 if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) {
224 mRefreshPeriod = nsecs_t(period);
225 }
Jesse Hallb685c542012-07-31 14:32:56 -0700226 } else {
227 needVSyncThread = true;
Mathias Agopian028508c2012-07-25 21:12:12 -0700228 }
Jesse Hallb685c542012-07-31 14:32:56 -0700229
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700230 if (mHwc->registerProcs) {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700231 mCBContext->hwc = this;
232 mCBContext->procs.invalidate = &hook_invalidate;
233 mCBContext->procs.vsync = &hook_vsync;
234 mHwc->registerProcs(mHwc, &mCBContext->procs);
235 memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700236 }
Jesse Hallb685c542012-07-31 14:32:56 -0700237
238 // create initial empty display contents for display 0
239 createWorkList(0);
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700240 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700241 }
242
Mathias Agopian888c8222012-08-04 21:10:38 -0700243 if (mRefreshPeriod == 0) {
244 // for compatibility, we attempt to get the refresh rate from
245 // the FB HAL if we couldn't get it from the HWC HAL.
246 hw_module_t const* module;
247 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
248 framebuffer_device_t* fbDev;
249 int err = framebuffer_open(module, &fbDev);
250 if (!err && fbDev) {
251 mRefreshPeriod = nsecs_t(1e9 / fbDev->fps);
252 framebuffer_close(fbDev);
253 }
254 }
255 ALOGW("getting VSYNC period from fb HAL: %lld", mRefreshPeriod);
256 }
257
258 if (mRefreshPeriod == 0) {
259 mRefreshPeriod = nsecs_t(1e9 / 60.0);
260 ALOGW("getting VSYNC period thin air: %lld", mRefreshPeriod);
261 }
262
Mathias Agopian3a778712012-04-09 14:16:47 -0700263 if (needVSyncThread) {
264 // we don't have VSYNC support, we need to fake it
265 mVSyncThread = new VSyncThread(*this);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700266 }
267}
268
269HWComposer::~HWComposer() {
Jesse Hallb685c542012-07-31 14:32:56 -0700270 hwcEventControl(mHwc, 0, EVENT_VSYNC, 0);
271 for (size_t i = 0; i < MAX_DISPLAYS; i++)
272 free(mLists[i]);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700273 if (mVSyncThread != NULL) {
274 mVSyncThread->requestExitAndWait();
275 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700276 if (mHwc) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700277 hwc_close_1(mHwc);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700278 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700279 delete mCBContext;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700280}
281
282status_t HWComposer::initCheck() const {
283 return mHwc ? NO_ERROR : NO_INIT;
284}
285
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700286void HWComposer::hook_invalidate(struct hwc_procs* procs) {
287 reinterpret_cast<cb_context *>(procs)->hwc->invalidate();
288}
289
Mathias Agopian31d28432012-04-03 16:31:39 -0700290void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) {
291 reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp);
292}
293
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700294void HWComposer::invalidate() {
Mathias Agopiane2c2f922011-10-05 15:00:22 -0700295 mFlinger->repaintEverything();
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700296}
297
Mathias Agopian31d28432012-04-03 16:31:39 -0700298void HWComposer::vsync(int dpy, int64_t timestamp) {
Mathias Agopian2965b262012-04-08 15:13:32 -0700299 ATRACE_INT("VSYNC", ++mVSyncCount&1);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700300 mEventHandler.onVSyncReceived(dpy, timestamp);
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700301 Mutex::Autolock _l(mLock);
302 mLastHwVSync = timestamp;
303}
304
Mathias Agopian888c8222012-08-04 21:10:38 -0700305nsecs_t HWComposer::getRefreshPeriod() const {
306 return mRefreshPeriod;
307}
308
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700309nsecs_t HWComposer::getRefreshTimestamp() const {
310 // this returns the last refresh timestamp.
311 // if the last one is not available, we estimate it based on
312 // the refresh period and whatever closest timestamp we have.
313 Mutex::Autolock _l(mLock);
314 nsecs_t now = systemTime(CLOCK_MONOTONIC);
315 return now - ((now - mLastHwVSync) % mRefreshPeriod);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700316}
317
Mathias Agopian03e40722012-04-26 16:11:59 -0700318void HWComposer::eventControl(int event, int enabled) {
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700319 status_t err = NO_ERROR;
Erik Gilling1a3bf412012-04-06 14:13:32 -0700320 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700321 if (!mDebugForceFakeVSync) {
Jesse Hallb685c542012-07-31 14:32:56 -0700322 err = hwcEventControl(mHwc, 0, event, enabled);
Mathias Agopian03e40722012-04-26 16:11:59 -0700323 // error here should not happen -- not sure what we should
324 // do if it does.
325 ALOGE_IF(err, "eventControl(%d, %d) failed %s",
326 event, enabled, strerror(-err));
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700327 }
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700328 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700329
330 if (err == NO_ERROR && mVSyncThread != NULL) {
331 mVSyncThread->setEnabled(enabled);
332 }
Mathias Agopian31d28432012-04-03 16:31:39 -0700333}
334
Mathias Agopiana350ff92010-08-10 17:14:02 -0700335status_t HWComposer::createWorkList(size_t numLayers) {
Mathias Agopian45721772010-08-12 15:03:26 -0700336 if (mHwc) {
Jesse Hallb685c542012-07-31 14:32:56 -0700337 // mLists[0] is NULL only when this is called from the constructor
338 if (!mLists[0] || mCapacity < numLayers) {
339 free(mLists[0]);
Jesse Hall5880cc52012-06-05 23:40:32 -0700340 size_t size = sizeofHwcLayerList(mHwc, numLayers);
Jesse Hallb685c542012-07-31 14:32:56 -0700341 mLists[0] = (hwc_display_contents_1_t*)malloc(size);
Mathias Agopian45721772010-08-12 15:03:26 -0700342 mCapacity = numLayers;
343 }
Jesse Hallb685c542012-07-31 14:32:56 -0700344 hwcFlags(mHwc, mLists[0]) = HWC_GEOMETRY_CHANGED;
345 hwcNumHwLayers(mHwc, mLists[0]) = numLayers;
346 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
347 mLists[0]->flipFenceFd = -1;
348 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700349 }
350 return NO_ERROR;
351}
352
353status_t HWComposer::prepare() const {
Jesse Hallb685c542012-07-31 14:32:56 -0700354 int err = hwcPrepare(mHwc, 1,
355 const_cast<hwc_display_contents_1_t**>(mLists));
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700356 if (err == NO_ERROR) {
357 size_t numOVLayers = 0;
358 size_t numFBLayers = 0;
Jesse Hallb685c542012-07-31 14:32:56 -0700359 size_t count = getNumLayers();
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700360 for (size_t i=0 ; i<count ; i++) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700361 hwc_layer_1_t* l = NULL;
362 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
Jesse Hallb685c542012-07-31 14:32:56 -0700363 l = &mLists[0]->hwLayers[i];
Jesse Hall5880cc52012-06-05 23:40:32 -0700364 } else {
365 // mList really has hwc_layer_list_t memory layout
Jesse Hallb685c542012-07-31 14:32:56 -0700366 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0];
367 hwc_layer_t* layer = &list0->hwLayers[i];
Jesse Hall5880cc52012-06-05 23:40:32 -0700368 l = (hwc_layer_1_t*)layer;
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700369 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700370 if (l->flags & HWC_SKIP_LAYER) {
371 l->compositionType = HWC_FRAMEBUFFER;
372 }
373 switch (l->compositionType) {
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700374 case HWC_OVERLAY:
375 numOVLayers++;
376 break;
377 case HWC_FRAMEBUFFER:
378 numFBLayers++;
379 break;
380 }
381 }
382 mNumOVLayers = numOVLayers;
383 mNumFBLayers = numFBLayers;
384 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700385 return (status_t)err;
386}
387
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700388size_t HWComposer::getLayerCount(int type) const {
389 switch (type) {
390 case HWC_OVERLAY:
391 return mNumOVLayers;
392 case HWC_FRAMEBUFFER:
393 return mNumFBLayers;
394 }
395 return 0;
396}
397
Jesse Hall34a09ba2012-07-29 22:35:34 -0700398status_t HWComposer::commit(void* fbDisplay, void* fbSurface) const {
Mathias Agopian86303202012-07-24 22:46:10 -0700399 int err = NO_ERROR;
400 if (mHwc) {
Jesse Hallb685c542012-07-31 14:32:56 -0700401 err = hwcSet(mHwc, fbDisplay, fbSurface, 1,
402 const_cast<hwc_display_contents_1_t**>(mLists));
403 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
404 if (mLists[0]->flipFenceFd != -1) {
405 close(mLists[0]->flipFenceFd);
406 mLists[0]->flipFenceFd = -1;
407 }
Mathias Agopian86303202012-07-24 22:46:10 -0700408 }
Jesse Hallb685c542012-07-31 14:32:56 -0700409 hwcFlags(mHwc, mLists[0]) &= ~HWC_GEOMETRY_CHANGED;
Mathias Agopian58959342010-10-07 14:57:04 -0700410 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700411 return (status_t)err;
412}
413
Antti Hatalaf5f27122010-09-09 02:33:05 -0700414status_t HWComposer::release() const {
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700415 if (mHwc) {
Jesse Hallb685c542012-07-31 14:32:56 -0700416 if (hwcHasVsyncEvent(mHwc)) {
417 hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
Mathias Agopian22ffb112012-04-10 21:04:02 -0700418 }
Jesse Hallb685c542012-07-31 14:32:56 -0700419 return (status_t)hwcBlank(mHwc, 0, 1);
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700420 }
421 return NO_ERROR;
422}
423
Colin Cross10fbdb62012-07-12 17:56:34 -0700424status_t HWComposer::acquire() const {
425 if (mHwc) {
Jesse Hallb685c542012-07-31 14:32:56 -0700426 return (status_t)hwcBlank(mHwc, 0, 0);
Colin Cross10fbdb62012-07-12 17:56:34 -0700427 }
Colin Cross10fbdb62012-07-12 17:56:34 -0700428 return NO_ERROR;
429}
430
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700431status_t HWComposer::disable() {
432 if (mHwc) {
Jesse Hallb685c542012-07-31 14:32:56 -0700433 hwcNumHwLayers(mHwc, mLists[0]) = 0;
434 int err = hwcPrepare(mHwc, 1, mLists);
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700435 return (status_t)err;
436 }
437 return NO_ERROR;
Antti Hatalaf5f27122010-09-09 02:33:05 -0700438}
439
Mathias Agopian45721772010-08-12 15:03:26 -0700440size_t HWComposer::getNumLayers() const {
Jesse Hallb685c542012-07-31 14:32:56 -0700441 return mHwc ? hwcNumHwLayers(mHwc, mLists[0]) : 0;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700442}
443
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700444/*
445 * Helper template to implement a concrete HWCLayer
446 * This holds the pointer to the concrete hwc layer type
447 * and implements the "iterable" side of HWCLayer.
448 */
449template<typename CONCRETE, typename HWCTYPE>
450class Iterable : public HWComposer::HWCLayer {
451protected:
452 HWCTYPE* const mLayerList;
453 HWCTYPE* mCurrentLayer;
454 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
455 inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
456 inline HWCTYPE* getLayer() { return mCurrentLayer; }
457 virtual ~Iterable() { }
458private:
459 // returns a copy of ourselves
460 virtual HWComposer::HWCLayer* dup() {
461 return new CONCRETE( static_cast<const CONCRETE&>(*this) );
462 }
463 virtual status_t setLayer(size_t index) {
464 mCurrentLayer = &mLayerList[index];
465 return NO_ERROR;
466 }
467};
468
Jesse Hall5880cc52012-06-05 23:40:32 -0700469// #if !HWC_REMOVE_DEPRECATED_VERSIONS
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700470/*
471 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
472 * This implements the HWCLayer side of HWCIterableLayer.
473 */
Jesse Hall5880cc52012-06-05 23:40:32 -0700474class HWCLayerVersion0 : public Iterable<HWCLayerVersion0, hwc_layer_t> {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700475public:
Jesse Hall5880cc52012-06-05 23:40:32 -0700476 HWCLayerVersion0(hwc_layer_t* layer)
477 : Iterable<HWCLayerVersion0, hwc_layer_t>(layer) { }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700478
479 virtual int32_t getCompositionType() const {
480 return getLayer()->compositionType;
481 }
482 virtual uint32_t getHints() const {
483 return getLayer()->hints;
484 }
Jesse Hallef194142012-06-14 14:45:17 -0700485 virtual int getAndResetReleaseFenceFd() {
486 // not supported on VERSION_03
487 return -1;
488 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700489 virtual void setAcquireFenceFd(int fenceFd) {
490 if (fenceFd != -1) {
491 ALOGE("HWC 0.x can't handle acquire fences");
492 close(fenceFd);
493 }
494 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700495
496 virtual void setDefaultState() {
497 getLayer()->compositionType = HWC_FRAMEBUFFER;
498 getLayer()->hints = 0;
499 getLayer()->flags = HWC_SKIP_LAYER;
500 getLayer()->transform = 0;
501 getLayer()->blending = HWC_BLENDING_NONE;
502 getLayer()->visibleRegionScreen.numRects = 0;
503 getLayer()->visibleRegionScreen.rects = NULL;
504 }
505 virtual void setSkip(bool skip) {
506 if (skip) {
507 getLayer()->flags |= HWC_SKIP_LAYER;
508 } else {
509 getLayer()->flags &= ~HWC_SKIP_LAYER;
510 }
511 }
512 virtual void setBlending(uint32_t blending) {
513 getLayer()->blending = blending;
514 }
515 virtual void setTransform(uint32_t transform) {
516 getLayer()->transform = transform;
517 }
518 virtual void setFrame(const Rect& frame) {
519 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
520 }
521 virtual void setCrop(const Rect& crop) {
522 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
523 }
524 virtual void setVisibleRegionScreen(const Region& reg) {
525 getLayer()->visibleRegionScreen.rects =
526 reinterpret_cast<hwc_rect_t const *>(
527 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
528 }
529 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
530 if (buffer == 0 || buffer->handle == 0) {
531 getLayer()->compositionType = HWC_FRAMEBUFFER;
532 getLayer()->flags |= HWC_SKIP_LAYER;
533 getLayer()->handle = 0;
534 } else {
535 getLayer()->handle = buffer->handle;
536 }
537 }
538};
Jesse Hall5880cc52012-06-05 23:40:32 -0700539// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS
540
541/*
542 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
543 * This implements the HWCLayer side of HWCIterableLayer.
544 */
545class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> {
546public:
547 HWCLayerVersion1(hwc_layer_1_t* layer)
548 : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer) { }
549
550 virtual int32_t getCompositionType() const {
551 return getLayer()->compositionType;
552 }
553 virtual uint32_t getHints() const {
554 return getLayer()->hints;
555 }
Jesse Hallef194142012-06-14 14:45:17 -0700556 virtual int getAndResetReleaseFenceFd() {
557 int fd = getLayer()->releaseFenceFd;
558 getLayer()->releaseFenceFd = -1;
559 return fd;
560 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700561 virtual void setAcquireFenceFd(int fenceFd) {
562 getLayer()->acquireFenceFd = fenceFd;
563 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700564
565 virtual void setDefaultState() {
566 getLayer()->compositionType = HWC_FRAMEBUFFER;
567 getLayer()->hints = 0;
568 getLayer()->flags = HWC_SKIP_LAYER;
569 getLayer()->transform = 0;
570 getLayer()->blending = HWC_BLENDING_NONE;
571 getLayer()->visibleRegionScreen.numRects = 0;
572 getLayer()->visibleRegionScreen.rects = NULL;
573 getLayer()->acquireFenceFd = -1;
574 getLayer()->releaseFenceFd = -1;
575 }
576 virtual void setSkip(bool skip) {
577 if (skip) {
578 getLayer()->flags |= HWC_SKIP_LAYER;
579 } else {
580 getLayer()->flags &= ~HWC_SKIP_LAYER;
581 }
582 }
583 virtual void setBlending(uint32_t blending) {
584 getLayer()->blending = blending;
585 }
586 virtual void setTransform(uint32_t transform) {
587 getLayer()->transform = transform;
588 }
589 virtual void setFrame(const Rect& frame) {
590 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
591 }
592 virtual void setCrop(const Rect& crop) {
593 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
594 }
595 virtual void setVisibleRegionScreen(const Region& reg) {
596 getLayer()->visibleRegionScreen.rects =
597 reinterpret_cast<hwc_rect_t const *>(
598 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
599 }
600 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
601 if (buffer == 0 || buffer->handle == 0) {
602 getLayer()->compositionType = HWC_FRAMEBUFFER;
603 getLayer()->flags |= HWC_SKIP_LAYER;
604 getLayer()->handle = 0;
605 } else {
606 getLayer()->handle = buffer->handle;
607 }
608 }
609};
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700610
611/*
612 * returns an iterator initialized at a given index in the layer list
613 */
614HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) {
Jesse Hallb685c542012-07-31 14:32:56 -0700615 if (index > hwcNumHwLayers(mHwc, mLists[0]))
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700616 return LayerListIterator();
Jesse Hall5880cc52012-06-05 23:40:32 -0700617 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
Jesse Hallb685c542012-07-31 14:32:56 -0700618 return LayerListIterator(new HWCLayerVersion1(mLists[0]->hwLayers),
619 index);
Jesse Hall5880cc52012-06-05 23:40:32 -0700620 } else {
Jesse Hallb685c542012-07-31 14:32:56 -0700621 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0];
Jesse Hall5880cc52012-06-05 23:40:32 -0700622 return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index);
623 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700624}
625
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700626/*
627 * returns an iterator on the beginning of the layer list
628 */
629HWComposer::LayerListIterator HWComposer::begin() {
630 return getLayerIterator(0);
631}
632
633/*
634 * returns an iterator on the end of the layer list
635 */
636HWComposer::LayerListIterator HWComposer::end() {
637 return getLayerIterator(getNumLayers());
638}
639
Mathias Agopian22da60c2011-09-09 00:49:11 -0700640void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
641 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
Jesse Hallb685c542012-07-31 14:32:56 -0700642 if (mHwc) {
643 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0];
644
Mathias Agopian83727852010-09-23 18:13:21 -0700645 result.append("Hardware Composer state:\n");
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700646 result.appendFormat(" mDebugForceFakeVSync=%d\n",
647 mDebugForceFakeVSync);
648 result.appendFormat(" numHwLayers=%u, flags=%08x\n",
Jesse Hallb685c542012-07-31 14:32:56 -0700649 hwcNumHwLayers(mHwc, mLists[0]), hwcFlags(mHwc, mLists[0]));
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700650 result.append(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700651 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n"
652 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
653 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
Jesse Hallb685c542012-07-31 14:32:56 -0700654 for (size_t i=0 ; i<hwcNumHwLayers(mHwc, mLists[0]) ; i++) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700655 hwc_layer_1_t l;
656 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
Jesse Hallb685c542012-07-31 14:32:56 -0700657 l = mLists[0]->hwLayers[i];
Jesse Hall5880cc52012-06-05 23:40:32 -0700658 } else {
Jesse Hallb685c542012-07-31 14:32:56 -0700659 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0];
Jesse Hall5880cc52012-06-05 23:40:32 -0700660 *(hwc_layer_t*)&l = list0->hwLayers[i];
661 l.acquireFenceFd = l.releaseFenceFd = -1;
662 }
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700663 const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
664 int32_t format = -1;
665 if (layer->getLayer() != NULL) {
666 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
667 if (buffer != NULL) {
668 format = buffer->getPixelFormat();
669 }
670 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700671 result.appendFormat(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700672 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700673 l.compositionType ? "OVERLAY" : "FB",
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700674 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
Mathias Agopian83727852010-09-23 18:13:21 -0700675 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
Mathias Agopian22da60c2011-09-09 00:49:11 -0700676 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700677 layer->getName().string());
Mathias Agopian83727852010-09-23 18:13:21 -0700678 }
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800679 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700680 if (mHwc && hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_1) && mHwc->dump) {
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800681 mHwc->dump(mHwc, buffer, SIZE);
682 result.append(buffer);
Mathias Agopian83727852010-09-23 18:13:21 -0700683 }
684}
685
Mathias Agopiana350ff92010-08-10 17:14:02 -0700686// ---------------------------------------------------------------------------
Mathias Agopian2965b262012-04-08 15:13:32 -0700687
688HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
689 : mHwc(hwc), mEnabled(false),
690 mNextFakeVSync(0),
691 mRefreshPeriod(hwc.mRefreshPeriod)
692{
693}
694
695void HWComposer::VSyncThread::setEnabled(bool enabled) {
696 Mutex::Autolock _l(mLock);
697 mEnabled = enabled;
698 mCondition.signal();
699}
700
701void HWComposer::VSyncThread::onFirstRef() {
702 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
703}
704
705bool HWComposer::VSyncThread::threadLoop() {
706 { // scope for lock
707 Mutex::Autolock _l(mLock);
708 while (!mEnabled) {
709 mCondition.wait(mLock);
710 }
711 }
712
713 const nsecs_t period = mRefreshPeriod;
714 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
715 nsecs_t next_vsync = mNextFakeVSync;
716 nsecs_t sleep = next_vsync - now;
717 if (sleep < 0) {
718 // we missed, find where the next vsync should be
719 sleep = (period - ((now - next_vsync) % period));
720 next_vsync = now + sleep;
721 }
722 mNextFakeVSync = next_vsync + period;
723
724 struct timespec spec;
725 spec.tv_sec = next_vsync / 1000000000;
726 spec.tv_nsec = next_vsync % 1000000000;
727
728 int err;
729 do {
730 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
731 } while (err<0 && errno == EINTR);
732
733 if (err == 0) {
734 mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
735 }
736
737 return true;
738}
739
740// ---------------------------------------------------------------------------
Mathias Agopiana350ff92010-08-10 17:14:02 -0700741}; // namespace android