blob: 2a51fb66c6a67c10c52b901d4e0237b63f7ad63a [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
53// allocate v0.3 structures, but assign them to v1.0 pointers. Fields that
54// exist in both versions are located at the same offset, so in most cases we
55// can just use the v1.0 pointer without branches or casts.
56
57#if HWC_REMOVE_DEPRECATED_VERSIONS
58// We need complete types with to satisfy semantic checks, even though the
59// code paths that use these won't get executed at runtime (and will likely be
60// dead-code-eliminated). When we remove the code to support v0.3 we can remove
61// these as well.
62typedef hwc_layer_1_t hwc_layer_t;
63typedef hwc_layer_list_1_t hwc_layer_list_t;
64typedef hwc_composer_device_1_t hwc_composer_device_t;
65#endif
66
67// This function assumes we've already rejected HWC's with lower-than-required
68// versions. Don't use it for the initial "does HWC meet requirements" check!
69static bool hwcHasVersion(const hwc_composer_device_1_t* hwc, uint32_t version) {
70 if (HWC_REMOVE_DEPRECATED_VERSIONS &&
71 version <= HWC_DEVICE_API_VERSION_1_0) {
72 return true;
73 } else {
74 return hwc->common.version >= version;
75 }
76}
77
78static size_t sizeofHwcLayerList(const hwc_composer_device_1_t* hwc,
79 size_t numLayers) {
80 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
81 return sizeof(hwc_layer_list_1_t) + numLayers*sizeof(hwc_layer_1_t);
82 } else {
83 return sizeof(hwc_layer_list_t) + numLayers*sizeof(hwc_layer_t);
84 }
85}
86
Mathias Agopiana350ff92010-08-10 17:14:02 -070087// ---------------------------------------------------------------------------
88
Mathias Agopian3e8b8532012-05-13 20:42:01 -070089struct HWComposer::cb_context {
90 struct callbacks : public hwc_procs_t {
91 // these are here to facilitate the transition when adding
92 // new callbacks (an implementation can check for NULL before
93 // calling a new callback).
94 void (*zero[4])(void);
95 };
96 callbacks procs;
97 HWComposer* hwc;
98};
99
100// ---------------------------------------------------------------------------
101
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700102HWComposer::HWComposer(
103 const sp<SurfaceFlinger>& flinger,
Mathias Agopian888c8222012-08-04 21:10:38 -0700104 EventHandler& handler)
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700105 : mFlinger(flinger),
106 mModule(0), mHwc(0), mList(0), mCapacity(0),
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700107 mNumOVLayers(0), mNumFBLayers(0),
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700108 mCBContext(new cb_context),
Mathias Agopian888c8222012-08-04 21:10:38 -0700109 mEventHandler(handler), mRefreshPeriod(0),
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700110 mVSyncCount(0), mDebugForceFakeVSync(false)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700111{
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700112 char value[PROPERTY_VALUE_MAX];
113 property_get("debug.sf.no_hw_vsync", value, "0");
114 mDebugForceFakeVSync = atoi(value);
115
Mathias Agopian028508c2012-07-25 21:12:12 -0700116 bool needVSyncThread = true;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700117 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
Steve Block32397c12012-01-05 23:22:43 +0000118 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700119 if (err == 0) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700120 err = hwc_open_1(mModule, &mHwc);
Steve Blocke6f43dd2012-01-06 19:20:56 +0000121 ALOGE_IF(err, "%s device failed to initialize (%s)",
Mathias Agopiana350ff92010-08-10 17:14:02 -0700122 HWC_HARDWARE_COMPOSER, strerror(-err));
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700123 if (err == 0) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700124 if (HWC_REMOVE_DEPRECATED_VERSIONS &&
125 mHwc->common.version < HWC_DEVICE_API_VERSION_1_0) {
126 ALOGE("%s device version %#x too old, will not be used",
127 HWC_HARDWARE_COMPOSER, mHwc->common.version);
128 hwc_close_1(mHwc);
129 mHwc = NULL;
130 }
131 }
132
133 if (mHwc) {
Mathias Agopian028508c2012-07-25 21:12:12 -0700134 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_3)) {
135 // always turn vsync off when we start
136 mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0);
137 needVSyncThread = false;
Mathias Agopian888c8222012-08-04 21:10:38 -0700138
139 int period;
140 if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) {
141 mRefreshPeriod = nsecs_t(period);
142 }
Mathias Agopian028508c2012-07-25 21:12:12 -0700143 }
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700144 if (mHwc->registerProcs) {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700145 mCBContext->hwc = this;
146 mCBContext->procs.invalidate = &hook_invalidate;
147 mCBContext->procs.vsync = &hook_vsync;
148 mHwc->registerProcs(mHwc, &mCBContext->procs);
149 memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700150 }
151 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700152 }
153
Mathias Agopian888c8222012-08-04 21:10:38 -0700154 if (mRefreshPeriod == 0) {
155 // for compatibility, we attempt to get the refresh rate from
156 // the FB HAL if we couldn't get it from the HWC HAL.
157 hw_module_t const* module;
158 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
159 framebuffer_device_t* fbDev;
160 int err = framebuffer_open(module, &fbDev);
161 if (!err && fbDev) {
162 mRefreshPeriod = nsecs_t(1e9 / fbDev->fps);
163 framebuffer_close(fbDev);
164 }
165 }
166 ALOGW("getting VSYNC period from fb HAL: %lld", mRefreshPeriod);
167 }
168
169 if (mRefreshPeriod == 0) {
170 mRefreshPeriod = nsecs_t(1e9 / 60.0);
171 ALOGW("getting VSYNC period thin air: %lld", mRefreshPeriod);
172 }
173
Mathias Agopian3a778712012-04-09 14:16:47 -0700174 if (needVSyncThread) {
175 // we don't have VSYNC support, we need to fake it
176 mVSyncThread = new VSyncThread(*this);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700177 }
178}
179
180HWComposer::~HWComposer() {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700181 eventControl(EVENT_VSYNC, 0);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700182 free(mList);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700183 if (mVSyncThread != NULL) {
184 mVSyncThread->requestExitAndWait();
185 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700186 if (mHwc) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700187 hwc_close_1(mHwc);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700188 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700189 delete mCBContext;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700190}
191
192status_t HWComposer::initCheck() const {
193 return mHwc ? NO_ERROR : NO_INIT;
194}
195
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700196void HWComposer::hook_invalidate(struct hwc_procs* procs) {
197 reinterpret_cast<cb_context *>(procs)->hwc->invalidate();
198}
199
Mathias Agopian31d28432012-04-03 16:31:39 -0700200void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) {
201 reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp);
202}
203
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700204void HWComposer::invalidate() {
Mathias Agopiane2c2f922011-10-05 15:00:22 -0700205 mFlinger->repaintEverything();
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700206}
207
Mathias Agopian31d28432012-04-03 16:31:39 -0700208void HWComposer::vsync(int dpy, int64_t timestamp) {
Mathias Agopian2965b262012-04-08 15:13:32 -0700209 ATRACE_INT("VSYNC", ++mVSyncCount&1);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700210 mEventHandler.onVSyncReceived(dpy, timestamp);
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700211 Mutex::Autolock _l(mLock);
212 mLastHwVSync = timestamp;
213}
214
Mathias Agopian888c8222012-08-04 21:10:38 -0700215nsecs_t HWComposer::getRefreshPeriod() const {
216 return mRefreshPeriod;
217}
218
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700219nsecs_t HWComposer::getRefreshTimestamp() const {
220 // this returns the last refresh timestamp.
221 // if the last one is not available, we estimate it based on
222 // the refresh period and whatever closest timestamp we have.
223 Mutex::Autolock _l(mLock);
224 nsecs_t now = systemTime(CLOCK_MONOTONIC);
225 return now - ((now - mLastHwVSync) % mRefreshPeriod);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700226}
227
Mathias Agopian03e40722012-04-26 16:11:59 -0700228void HWComposer::eventControl(int event, int enabled) {
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700229 status_t err = NO_ERROR;
Erik Gilling1a3bf412012-04-06 14:13:32 -0700230 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700231 if (!mDebugForceFakeVSync) {
232 err = mHwc->methods->eventControl(mHwc, event, enabled);
Mathias Agopian03e40722012-04-26 16:11:59 -0700233 // error here should not happen -- not sure what we should
234 // do if it does.
235 ALOGE_IF(err, "eventControl(%d, %d) failed %s",
236 event, enabled, strerror(-err));
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700237 }
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700238 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700239
240 if (err == NO_ERROR && mVSyncThread != NULL) {
241 mVSyncThread->setEnabled(enabled);
242 }
Mathias Agopian31d28432012-04-03 16:31:39 -0700243}
244
Mathias Agopiana350ff92010-08-10 17:14:02 -0700245status_t HWComposer::createWorkList(size_t numLayers) {
Mathias Agopian45721772010-08-12 15:03:26 -0700246 if (mHwc) {
247 if (!mList || mCapacity < numLayers) {
248 free(mList);
Jesse Hall5880cc52012-06-05 23:40:32 -0700249 size_t size = sizeofHwcLayerList(mHwc, numLayers);
250 mList = (hwc_layer_list_1_t*)malloc(size);
Mathias Agopian45721772010-08-12 15:03:26 -0700251 mCapacity = numLayers;
252 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700253 mList->flags = HWC_GEOMETRY_CHANGED;
254 mList->numHwLayers = numLayers;
255 }
256 return NO_ERROR;
257}
258
259status_t HWComposer::prepare() const {
260 int err = mHwc->prepare(mHwc, mList);
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700261 if (err == NO_ERROR) {
262 size_t numOVLayers = 0;
263 size_t numFBLayers = 0;
264 size_t count = mList->numHwLayers;
265 for (size_t i=0 ; i<count ; i++) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700266 hwc_layer_1_t* l = NULL;
267 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
268 l = &mList->hwLayers[i];
269 } else {
270 // mList really has hwc_layer_list_t memory layout
271 hwc_layer_list_t* list = (hwc_layer_list_t*)mList;
272 hwc_layer_t* layer = &list->hwLayers[i];
273 l = (hwc_layer_1_t*)layer;
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700274 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700275 if (l->flags & HWC_SKIP_LAYER) {
276 l->compositionType = HWC_FRAMEBUFFER;
277 }
278 switch (l->compositionType) {
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700279 case HWC_OVERLAY:
280 numOVLayers++;
281 break;
282 case HWC_FRAMEBUFFER:
283 numFBLayers++;
284 break;
285 }
286 }
287 mNumOVLayers = numOVLayers;
288 mNumFBLayers = numFBLayers;
289 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700290 return (status_t)err;
291}
292
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700293size_t HWComposer::getLayerCount(int type) const {
294 switch (type) {
295 case HWC_OVERLAY:
296 return mNumOVLayers;
297 case HWC_FRAMEBUFFER:
298 return mNumFBLayers;
299 }
300 return 0;
301}
302
Jesse Hall34a09ba2012-07-29 22:35:34 -0700303status_t HWComposer::commit(void* fbDisplay, void* fbSurface) const {
Mathias Agopian86303202012-07-24 22:46:10 -0700304 int err = NO_ERROR;
305 if (mHwc) {
Jesse Hall34a09ba2012-07-29 22:35:34 -0700306 err = mHwc->set(mHwc, fbDisplay, fbSurface, mList);
Mathias Agopian86303202012-07-24 22:46:10 -0700307 if (mList) {
308 mList->flags &= ~HWC_GEOMETRY_CHANGED;
309 }
Mathias Agopian58959342010-10-07 14:57:04 -0700310 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700311 return (status_t)err;
312}
313
Antti Hatalaf5f27122010-09-09 02:33:05 -0700314status_t HWComposer::release() const {
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700315 if (mHwc) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700316 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_3)) {
Mathias Agopian22ffb112012-04-10 21:04:02 -0700317 mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0);
318 }
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700319 int err = mHwc->set(mHwc, NULL, NULL, NULL);
Colin Cross10fbdb62012-07-12 17:56:34 -0700320 if (err < 0) {
321 return (status_t)err;
322 }
323
324 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
325 if (mHwc->methods && mHwc->methods->blank) {
326 err = mHwc->methods->blank(mHwc, 1);
327 }
328 }
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700329 return (status_t)err;
330 }
331 return NO_ERROR;
332}
333
Colin Cross10fbdb62012-07-12 17:56:34 -0700334status_t HWComposer::acquire() const {
335 if (mHwc) {
336 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
337 if (mHwc->methods && mHwc->methods->blank) {
338 int err = mHwc->methods->blank(mHwc, 0);
339 return (status_t)err;
340 }
341 }
342 }
343
344 return NO_ERROR;
345}
346
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700347status_t HWComposer::disable() {
348 if (mHwc) {
349 free(mList);
350 mList = NULL;
351 int err = mHwc->prepare(mHwc, NULL);
352 return (status_t)err;
353 }
354 return NO_ERROR;
Antti Hatalaf5f27122010-09-09 02:33:05 -0700355}
356
Mathias Agopian45721772010-08-12 15:03:26 -0700357size_t HWComposer::getNumLayers() const {
358 return mList ? mList->numHwLayers : 0;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700359}
360
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700361/*
362 * Helper template to implement a concrete HWCLayer
363 * This holds the pointer to the concrete hwc layer type
364 * and implements the "iterable" side of HWCLayer.
365 */
366template<typename CONCRETE, typename HWCTYPE>
367class Iterable : public HWComposer::HWCLayer {
368protected:
369 HWCTYPE* const mLayerList;
370 HWCTYPE* mCurrentLayer;
371 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
372 inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
373 inline HWCTYPE* getLayer() { return mCurrentLayer; }
374 virtual ~Iterable() { }
375private:
376 // returns a copy of ourselves
377 virtual HWComposer::HWCLayer* dup() {
378 return new CONCRETE( static_cast<const CONCRETE&>(*this) );
379 }
380 virtual status_t setLayer(size_t index) {
381 mCurrentLayer = &mLayerList[index];
382 return NO_ERROR;
383 }
384};
385
Jesse Hall5880cc52012-06-05 23:40:32 -0700386// #if !HWC_REMOVE_DEPRECATED_VERSIONS
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700387/*
388 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
389 * This implements the HWCLayer side of HWCIterableLayer.
390 */
Jesse Hall5880cc52012-06-05 23:40:32 -0700391class HWCLayerVersion0 : public Iterable<HWCLayerVersion0, hwc_layer_t> {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700392public:
Jesse Hall5880cc52012-06-05 23:40:32 -0700393 HWCLayerVersion0(hwc_layer_t* layer)
394 : Iterable<HWCLayerVersion0, hwc_layer_t>(layer) { }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700395
396 virtual int32_t getCompositionType() const {
397 return getLayer()->compositionType;
398 }
399 virtual uint32_t getHints() const {
400 return getLayer()->hints;
401 }
Jesse Hallef194142012-06-14 14:45:17 -0700402 virtual int getAndResetReleaseFenceFd() {
403 // not supported on VERSION_03
404 return -1;
405 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700406 virtual void setAcquireFenceFd(int fenceFd) {
407 if (fenceFd != -1) {
408 ALOGE("HWC 0.x can't handle acquire fences");
409 close(fenceFd);
410 }
411 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700412
413 virtual void setDefaultState() {
414 getLayer()->compositionType = HWC_FRAMEBUFFER;
415 getLayer()->hints = 0;
416 getLayer()->flags = HWC_SKIP_LAYER;
417 getLayer()->transform = 0;
418 getLayer()->blending = HWC_BLENDING_NONE;
419 getLayer()->visibleRegionScreen.numRects = 0;
420 getLayer()->visibleRegionScreen.rects = NULL;
421 }
422 virtual void setSkip(bool skip) {
423 if (skip) {
424 getLayer()->flags |= HWC_SKIP_LAYER;
425 } else {
426 getLayer()->flags &= ~HWC_SKIP_LAYER;
427 }
428 }
429 virtual void setBlending(uint32_t blending) {
430 getLayer()->blending = blending;
431 }
432 virtual void setTransform(uint32_t transform) {
433 getLayer()->transform = transform;
434 }
435 virtual void setFrame(const Rect& frame) {
436 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
437 }
438 virtual void setCrop(const Rect& crop) {
439 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
440 }
441 virtual void setVisibleRegionScreen(const Region& reg) {
442 getLayer()->visibleRegionScreen.rects =
443 reinterpret_cast<hwc_rect_t const *>(
444 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
445 }
446 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
447 if (buffer == 0 || buffer->handle == 0) {
448 getLayer()->compositionType = HWC_FRAMEBUFFER;
449 getLayer()->flags |= HWC_SKIP_LAYER;
450 getLayer()->handle = 0;
451 } else {
452 getLayer()->handle = buffer->handle;
453 }
454 }
455};
Jesse Hall5880cc52012-06-05 23:40:32 -0700456// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS
457
458/*
459 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
460 * This implements the HWCLayer side of HWCIterableLayer.
461 */
462class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> {
463public:
464 HWCLayerVersion1(hwc_layer_1_t* layer)
465 : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer) { }
466
467 virtual int32_t getCompositionType() const {
468 return getLayer()->compositionType;
469 }
470 virtual uint32_t getHints() const {
471 return getLayer()->hints;
472 }
Jesse Hallef194142012-06-14 14:45:17 -0700473 virtual int getAndResetReleaseFenceFd() {
474 int fd = getLayer()->releaseFenceFd;
475 getLayer()->releaseFenceFd = -1;
476 return fd;
477 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700478 virtual void setAcquireFenceFd(int fenceFd) {
479 getLayer()->acquireFenceFd = fenceFd;
480 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700481
482 virtual void setDefaultState() {
483 getLayer()->compositionType = HWC_FRAMEBUFFER;
484 getLayer()->hints = 0;
485 getLayer()->flags = HWC_SKIP_LAYER;
486 getLayer()->transform = 0;
487 getLayer()->blending = HWC_BLENDING_NONE;
488 getLayer()->visibleRegionScreen.numRects = 0;
489 getLayer()->visibleRegionScreen.rects = NULL;
490 getLayer()->acquireFenceFd = -1;
491 getLayer()->releaseFenceFd = -1;
492 }
493 virtual void setSkip(bool skip) {
494 if (skip) {
495 getLayer()->flags |= HWC_SKIP_LAYER;
496 } else {
497 getLayer()->flags &= ~HWC_SKIP_LAYER;
498 }
499 }
500 virtual void setBlending(uint32_t blending) {
501 getLayer()->blending = blending;
502 }
503 virtual void setTransform(uint32_t transform) {
504 getLayer()->transform = transform;
505 }
506 virtual void setFrame(const Rect& frame) {
507 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
508 }
509 virtual void setCrop(const Rect& crop) {
510 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
511 }
512 virtual void setVisibleRegionScreen(const Region& reg) {
513 getLayer()->visibleRegionScreen.rects =
514 reinterpret_cast<hwc_rect_t const *>(
515 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
516 }
517 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
518 if (buffer == 0 || buffer->handle == 0) {
519 getLayer()->compositionType = HWC_FRAMEBUFFER;
520 getLayer()->flags |= HWC_SKIP_LAYER;
521 getLayer()->handle = 0;
522 } else {
523 getLayer()->handle = buffer->handle;
524 }
525 }
526};
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700527
528/*
529 * returns an iterator initialized at a given index in the layer list
530 */
531HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) {
532 if (!mList || index > mList->numHwLayers) {
533 return LayerListIterator();
534 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700535 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
536 return LayerListIterator(new HWCLayerVersion1(mList->hwLayers), index);
537 } else {
538 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList;
539 return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index);
540 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700541}
542
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700543/*
544 * returns an iterator on the beginning of the layer list
545 */
546HWComposer::LayerListIterator HWComposer::begin() {
547 return getLayerIterator(0);
548}
549
550/*
551 * returns an iterator on the end of the layer list
552 */
553HWComposer::LayerListIterator HWComposer::end() {
554 return getLayerIterator(getNumLayers());
555}
556
557
558
Mathias Agopian22da60c2011-09-09 00:49:11 -0700559void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
560 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
Mathias Agopian83727852010-09-23 18:13:21 -0700561 if (mHwc && mList) {
562 result.append("Hardware Composer state:\n");
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700563 result.appendFormat(" mDebugForceFakeVSync=%d\n",
564 mDebugForceFakeVSync);
565 result.appendFormat(" numHwLayers=%u, flags=%08x\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700566 mList->numHwLayers, mList->flags);
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700567 result.append(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700568 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n"
569 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
570 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
Mathias Agopian83727852010-09-23 18:13:21 -0700571 for (size_t i=0 ; i<mList->numHwLayers ; i++) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700572 hwc_layer_1_t l;
573 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
574 l = mList->hwLayers[i];
575 } else {
576 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList;
577 *(hwc_layer_t*)&l = list0->hwLayers[i];
578 l.acquireFenceFd = l.releaseFenceFd = -1;
579 }
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700580 const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
581 int32_t format = -1;
582 if (layer->getLayer() != NULL) {
583 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
584 if (buffer != NULL) {
585 format = buffer->getPixelFormat();
586 }
587 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700588 result.appendFormat(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700589 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700590 l.compositionType ? "OVERLAY" : "FB",
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700591 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
Mathias Agopian83727852010-09-23 18:13:21 -0700592 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
Mathias Agopian22da60c2011-09-09 00:49:11 -0700593 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700594 layer->getName().string());
Mathias Agopian83727852010-09-23 18:13:21 -0700595 }
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800596 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700597 if (mHwc && hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_1) && mHwc->dump) {
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800598 mHwc->dump(mHwc, buffer, SIZE);
599 result.append(buffer);
Mathias Agopian83727852010-09-23 18:13:21 -0700600 }
601}
602
Mathias Agopiana350ff92010-08-10 17:14:02 -0700603// ---------------------------------------------------------------------------
Mathias Agopian2965b262012-04-08 15:13:32 -0700604
605HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
606 : mHwc(hwc), mEnabled(false),
607 mNextFakeVSync(0),
608 mRefreshPeriod(hwc.mRefreshPeriod)
609{
610}
611
612void HWComposer::VSyncThread::setEnabled(bool enabled) {
613 Mutex::Autolock _l(mLock);
614 mEnabled = enabled;
615 mCondition.signal();
616}
617
618void HWComposer::VSyncThread::onFirstRef() {
619 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
620}
621
622bool HWComposer::VSyncThread::threadLoop() {
623 { // scope for lock
624 Mutex::Autolock _l(mLock);
625 while (!mEnabled) {
626 mCondition.wait(mLock);
627 }
628 }
629
630 const nsecs_t period = mRefreshPeriod;
631 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
632 nsecs_t next_vsync = mNextFakeVSync;
633 nsecs_t sleep = next_vsync - now;
634 if (sleep < 0) {
635 // we missed, find where the next vsync should be
636 sleep = (period - ((now - next_vsync) % period));
637 next_vsync = now + sleep;
638 }
639 mNextFakeVSync = next_vsync + period;
640
641 struct timespec spec;
642 spec.tv_sec = next_vsync / 1000000000;
643 spec.tv_nsec = next_vsync % 1000000000;
644
645 int err;
646 do {
647 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
648 } while (err<0 && errno == EINTR);
649
650 if (err == 0) {
651 mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
652 }
653
654 return true;
655}
656
657// ---------------------------------------------------------------------------
Mathias Agopiana350ff92010-08-10 17:14:02 -0700658}; // namespace android