blob: 843815951119f1c75180d131ff447ad8efabcdc3 [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
42#include <EGL/egl.h>
43
Mathias Agopian921e6ac2012-07-23 23:11:29 -070044#include "Layer.h" // needed only for debugging
Mathias Agopian22da60c2011-09-09 00:49:11 -070045#include "LayerBase.h"
Mathias Agopiana350ff92010-08-10 17:14:02 -070046#include "HWComposer.h"
Mathias Agopianc7d14e22011-08-01 16:32:21 -070047#include "SurfaceFlinger.h"
Mathias Agopiana350ff92010-08-10 17:14:02 -070048
49namespace android {
Jesse Hall5880cc52012-06-05 23:40:32 -070050
51// ---------------------------------------------------------------------------
52// Support for HWC_DEVICE_API_VERSION_0_3 and older:
53// Since v0.3 is deprecated and support will be dropped soon, as much as
54// possible the code is written to target v1.0. When using a v0.3 HWC, we
55// allocate v0.3 structures, but assign them to v1.0 pointers. Fields that
56// exist in both versions are located at the same offset, so in most cases we
57// can just use the v1.0 pointer without branches or casts.
58
59#if HWC_REMOVE_DEPRECATED_VERSIONS
Jesse Hallbddd7242012-07-25 22:15:40 -070060// We need complete types to satisfy semantic checks, even though the code
61// paths that use these won't get executed at runtime (and will likely be dead-
62// code-eliminated). When we remove the code to support v0.3 we can remove
Jesse Hall5880cc52012-06-05 23:40:32 -070063// these as well.
64typedef hwc_layer_1_t hwc_layer_t;
Jesse Hallbddd7242012-07-25 22:15:40 -070065typedef hwc_display_contents_1_t hwc_layer_list_t;
Jesse Hall5880cc52012-06-05 23:40:32 -070066typedef hwc_composer_device_1_t hwc_composer_device_t;
67#endif
68
69// This function assumes we've already rejected HWC's with lower-than-required
70// versions. Don't use it for the initial "does HWC meet requirements" check!
71static bool hwcHasVersion(const hwc_composer_device_1_t* hwc, uint32_t version) {
72 if (HWC_REMOVE_DEPRECATED_VERSIONS &&
73 version <= HWC_DEVICE_API_VERSION_1_0) {
74 return true;
75 } else {
76 return hwc->common.version >= version;
77 }
78}
79
80static 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 Hallbddd7242012-07-25 22:15:40 -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
Mathias Agopiana350ff92010-08-10 17:14:02 -070089// ---------------------------------------------------------------------------
90
Mathias Agopian3e8b8532012-05-13 20:42:01 -070091struct HWComposer::cb_context {
92 struct callbacks : public hwc_procs_t {
93 // these are here to facilitate the transition when adding
94 // new callbacks (an implementation can check for NULL before
95 // calling a new callback).
96 void (*zero[4])(void);
97 };
98 callbacks procs;
99 HWComposer* hwc;
100};
101
102// ---------------------------------------------------------------------------
103
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700104HWComposer::HWComposer(
105 const sp<SurfaceFlinger>& flinger,
106 EventHandler& handler,
107 nsecs_t refreshPeriod)
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700108 : mFlinger(flinger),
109 mModule(0), mHwc(0), mList(0), mCapacity(0),
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700110 mNumOVLayers(0), mNumFBLayers(0),
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700111 mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE),
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700112 mCBContext(new cb_context),
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700113 mEventHandler(handler),
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700114 mRefreshPeriod(refreshPeriod),
115 mVSyncCount(0), mDebugForceFakeVSync(false)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700116{
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700117 char value[PROPERTY_VALUE_MAX];
118 property_get("debug.sf.no_hw_vsync", value, "0");
119 mDebugForceFakeVSync = atoi(value);
120
Mathias Agopian028508c2012-07-25 21:12:12 -0700121 bool needVSyncThread = true;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700122 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
Steve Block32397c12012-01-05 23:22:43 +0000123 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700124 if (err == 0) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700125 err = hwc_open_1(mModule, &mHwc);
Steve Blocke6f43dd2012-01-06 19:20:56 +0000126 ALOGE_IF(err, "%s device failed to initialize (%s)",
Mathias Agopiana350ff92010-08-10 17:14:02 -0700127 HWC_HARDWARE_COMPOSER, strerror(-err));
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700128 if (err == 0) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700129 if (HWC_REMOVE_DEPRECATED_VERSIONS &&
130 mHwc->common.version < HWC_DEVICE_API_VERSION_1_0) {
131 ALOGE("%s device version %#x too old, will not be used",
132 HWC_HARDWARE_COMPOSER, mHwc->common.version);
133 hwc_close_1(mHwc);
134 mHwc = NULL;
135 }
136 }
137
138 if (mHwc) {
Jesse Hallbddd7242012-07-25 22:15:40 -0700139 // always turn vsync off when we start
140 needVSyncThread = false;
141 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
142 mHwc->methods->eventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
143 } else if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_3)) {
144 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)mHwc;
145 err = hwc0->methods->eventControl(hwc0, HWC_EVENT_VSYNC, 0);
146 } else {
147 needVSyncThread = true;
Mathias Agopian028508c2012-07-25 21:12:12 -0700148 }
Jesse Hallbddd7242012-07-25 22:15:40 -0700149
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700150 if (mHwc->registerProcs) {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700151 mCBContext->hwc = this;
152 mCBContext->procs.invalidate = &hook_invalidate;
153 mCBContext->procs.vsync = &hook_vsync;
154 mHwc->registerProcs(mHwc, &mCBContext->procs);
155 memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700156 }
157 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700158 }
159
160 if (needVSyncThread) {
161 // we don't have VSYNC support, we need to fake it
162 mVSyncThread = new VSyncThread(*this);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700163 }
164}
165
166HWComposer::~HWComposer() {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700167 eventControl(EVENT_VSYNC, 0);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700168 free(mList);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700169 if (mVSyncThread != NULL) {
170 mVSyncThread->requestExitAndWait();
171 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700172 if (mHwc) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700173 hwc_close_1(mHwc);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700174 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700175 delete mCBContext;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700176}
177
178status_t HWComposer::initCheck() const {
179 return mHwc ? NO_ERROR : NO_INIT;
180}
181
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700182void HWComposer::hook_invalidate(struct hwc_procs* procs) {
183 reinterpret_cast<cb_context *>(procs)->hwc->invalidate();
184}
185
Mathias Agopian31d28432012-04-03 16:31:39 -0700186void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) {
187 reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp);
188}
189
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700190void HWComposer::invalidate() {
Mathias Agopiane2c2f922011-10-05 15:00:22 -0700191 mFlinger->repaintEverything();
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700192}
193
Mathias Agopian31d28432012-04-03 16:31:39 -0700194void HWComposer::vsync(int dpy, int64_t timestamp) {
Mathias Agopian2965b262012-04-08 15:13:32 -0700195 ATRACE_INT("VSYNC", ++mVSyncCount&1);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700196 mEventHandler.onVSyncReceived(dpy, timestamp);
197}
198
Mathias Agopian03e40722012-04-26 16:11:59 -0700199void HWComposer::eventControl(int event, int enabled) {
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700200 status_t err = NO_ERROR;
Erik Gilling1a3bf412012-04-06 14:13:32 -0700201 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700202 if (!mDebugForceFakeVSync) {
Jesse Hallbddd7242012-07-25 22:15:40 -0700203 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
204 err = mHwc->methods->eventControl(mHwc, 0, event, enabled);
205 } else {
206 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)mHwc;
207 err = hwc0->methods->eventControl(hwc0, event, enabled);
208 }
Mathias Agopian03e40722012-04-26 16:11:59 -0700209 // error here should not happen -- not sure what we should
210 // do if it does.
211 ALOGE_IF(err, "eventControl(%d, %d) failed %s",
212 event, enabled, strerror(-err));
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700213 }
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700214 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700215
216 if (err == NO_ERROR && mVSyncThread != NULL) {
217 mVSyncThread->setEnabled(enabled);
218 }
Mathias Agopian31d28432012-04-03 16:31:39 -0700219}
220
Mathias Agopiana350ff92010-08-10 17:14:02 -0700221void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
222 mDpy = (hwc_display_t)dpy;
223 mSur = (hwc_surface_t)sur;
224}
225
226status_t HWComposer::createWorkList(size_t numLayers) {
Mathias Agopian45721772010-08-12 15:03:26 -0700227 if (mHwc) {
228 if (!mList || mCapacity < numLayers) {
229 free(mList);
Jesse Hall5880cc52012-06-05 23:40:32 -0700230 size_t size = sizeofHwcLayerList(mHwc, numLayers);
Jesse Hallbddd7242012-07-25 22:15:40 -0700231 mList = (hwc_display_contents_1_t*)malloc(size);
Mathias Agopian45721772010-08-12 15:03:26 -0700232 mCapacity = numLayers;
Jesse Hallbddd7242012-07-25 22:15:40 -0700233 mList->flipFenceFd = -1;
Mathias Agopian45721772010-08-12 15:03:26 -0700234 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700235 mList->flags = HWC_GEOMETRY_CHANGED;
236 mList->numHwLayers = numLayers;
237 }
238 return NO_ERROR;
239}
240
241status_t HWComposer::prepare() const {
Jesse Hallbddd7242012-07-25 22:15:40 -0700242 int err = mHwc->prepare(mHwc, 1,
243 const_cast<hwc_display_contents_1_t**>(&mList));
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700244 if (err == NO_ERROR) {
245 size_t numOVLayers = 0;
246 size_t numFBLayers = 0;
247 size_t count = mList->numHwLayers;
248 for (size_t i=0 ; i<count ; i++) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700249 hwc_layer_1_t* l = NULL;
250 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
251 l = &mList->hwLayers[i];
252 } else {
253 // mList really has hwc_layer_list_t memory layout
254 hwc_layer_list_t* list = (hwc_layer_list_t*)mList;
255 hwc_layer_t* layer = &list->hwLayers[i];
256 l = (hwc_layer_1_t*)layer;
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700257 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700258 if (l->flags & HWC_SKIP_LAYER) {
259 l->compositionType = HWC_FRAMEBUFFER;
260 }
261 switch (l->compositionType) {
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700262 case HWC_OVERLAY:
263 numOVLayers++;
264 break;
265 case HWC_FRAMEBUFFER:
266 numFBLayers++;
267 break;
268 }
269 }
270 mNumOVLayers = numOVLayers;
271 mNumFBLayers = numFBLayers;
272 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700273 return (status_t)err;
274}
275
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700276size_t HWComposer::getLayerCount(int type) const {
277 switch (type) {
278 case HWC_OVERLAY:
279 return mNumOVLayers;
280 case HWC_FRAMEBUFFER:
281 return mNumFBLayers;
282 }
283 return 0;
284}
285
Mathias Agopiana350ff92010-08-10 17:14:02 -0700286status_t HWComposer::commit() const {
Mathias Agopian86303202012-07-24 22:46:10 -0700287 int err = NO_ERROR;
288 if (mHwc) {
Jesse Hallbddd7242012-07-25 22:15:40 -0700289 if (mList) {
290 mList->dpy = mDpy;
291 mList->sur = mSur;
292 }
293 err = mHwc->set(mHwc, 1, const_cast<hwc_display_contents_1_t**>(&mList));
Mathias Agopian86303202012-07-24 22:46:10 -0700294 if (mList) {
295 mList->flags &= ~HWC_GEOMETRY_CHANGED;
Jesse Hallbddd7242012-07-25 22:15:40 -0700296 if (mList->flipFenceFd != -1) {
297 close(mList->flipFenceFd);
298 mList->flipFenceFd = -1;
299 }
Mathias Agopian86303202012-07-24 22:46:10 -0700300 }
301 } else {
302 eglSwapBuffers(mDpy, mSur);
Mathias Agopian58959342010-10-07 14:57:04 -0700303 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700304 return (status_t)err;
305}
306
Antti Hatalaf5f27122010-09-09 02:33:05 -0700307status_t HWComposer::release() const {
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700308 if (mHwc) {
Jesse Hallbddd7242012-07-25 22:15:40 -0700309 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
310 mHwc->methods->eventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
311 } else if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_3)) {
312 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)mHwc;
313 hwc0->methods->eventControl(hwc0, HWC_EVENT_VSYNC, 0);
Mathias Agopian22ffb112012-04-10 21:04:02 -0700314 }
Jesse Hallbddd7242012-07-25 22:15:40 -0700315 int err = mHwc->set(mHwc, 0, NULL);
Colin Cross10fbdb62012-07-12 17:56:34 -0700316 if (err < 0) {
317 return (status_t)err;
318 }
319
320 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
321 if (mHwc->methods && mHwc->methods->blank) {
Jesse Hallbddd7242012-07-25 22:15:40 -0700322 err = mHwc->methods->blank(mHwc, 0, 1);
Colin Cross10fbdb62012-07-12 17:56:34 -0700323 }
324 }
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700325 return (status_t)err;
326 }
327 return NO_ERROR;
328}
329
Colin Cross10fbdb62012-07-12 17:56:34 -0700330status_t HWComposer::acquire() const {
331 if (mHwc) {
332 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
333 if (mHwc->methods && mHwc->methods->blank) {
Jesse Hallbddd7242012-07-25 22:15:40 -0700334 int err = mHwc->methods->blank(mHwc, 0, 0);
Colin Cross10fbdb62012-07-12 17:56:34 -0700335 return (status_t)err;
336 }
337 }
338 }
339
340 return NO_ERROR;
341}
342
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700343status_t HWComposer::disable() {
344 if (mHwc) {
345 free(mList);
346 mList = NULL;
Jesse Hallbddd7242012-07-25 22:15:40 -0700347 int err = mHwc->prepare(mHwc, 0, NULL);
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700348 return (status_t)err;
349 }
350 return NO_ERROR;
Antti Hatalaf5f27122010-09-09 02:33:05 -0700351}
352
Mathias Agopian45721772010-08-12 15:03:26 -0700353size_t HWComposer::getNumLayers() const {
354 return mList ? mList->numHwLayers : 0;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700355}
356
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700357/*
358 * Helper template to implement a concrete HWCLayer
359 * This holds the pointer to the concrete hwc layer type
360 * and implements the "iterable" side of HWCLayer.
361 */
362template<typename CONCRETE, typename HWCTYPE>
363class Iterable : public HWComposer::HWCLayer {
364protected:
365 HWCTYPE* const mLayerList;
366 HWCTYPE* mCurrentLayer;
367 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
368 inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
369 inline HWCTYPE* getLayer() { return mCurrentLayer; }
370 virtual ~Iterable() { }
371private:
372 // returns a copy of ourselves
373 virtual HWComposer::HWCLayer* dup() {
374 return new CONCRETE( static_cast<const CONCRETE&>(*this) );
375 }
376 virtual status_t setLayer(size_t index) {
377 mCurrentLayer = &mLayerList[index];
378 return NO_ERROR;
379 }
380};
381
Jesse Hall5880cc52012-06-05 23:40:32 -0700382// #if !HWC_REMOVE_DEPRECATED_VERSIONS
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700383/*
384 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
385 * This implements the HWCLayer side of HWCIterableLayer.
386 */
Jesse Hall5880cc52012-06-05 23:40:32 -0700387class HWCLayerVersion0 : public Iterable<HWCLayerVersion0, hwc_layer_t> {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700388public:
Jesse Hall5880cc52012-06-05 23:40:32 -0700389 HWCLayerVersion0(hwc_layer_t* layer)
390 : Iterable<HWCLayerVersion0, hwc_layer_t>(layer) { }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700391
392 virtual int32_t getCompositionType() const {
393 return getLayer()->compositionType;
394 }
395 virtual uint32_t getHints() const {
396 return getLayer()->hints;
397 }
Jesse Hallef194142012-06-14 14:45:17 -0700398 virtual int getAndResetReleaseFenceFd() {
399 // not supported on VERSION_03
400 return -1;
401 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700402 virtual void setAcquireFenceFd(int fenceFd) {
403 if (fenceFd != -1) {
404 ALOGE("HWC 0.x can't handle acquire fences");
405 close(fenceFd);
406 }
407 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700408
409 virtual void setDefaultState() {
410 getLayer()->compositionType = HWC_FRAMEBUFFER;
411 getLayer()->hints = 0;
412 getLayer()->flags = HWC_SKIP_LAYER;
413 getLayer()->transform = 0;
414 getLayer()->blending = HWC_BLENDING_NONE;
415 getLayer()->visibleRegionScreen.numRects = 0;
416 getLayer()->visibleRegionScreen.rects = NULL;
417 }
418 virtual void setSkip(bool skip) {
419 if (skip) {
420 getLayer()->flags |= HWC_SKIP_LAYER;
421 } else {
422 getLayer()->flags &= ~HWC_SKIP_LAYER;
423 }
424 }
425 virtual void setBlending(uint32_t blending) {
426 getLayer()->blending = blending;
427 }
428 virtual void setTransform(uint32_t transform) {
429 getLayer()->transform = transform;
430 }
431 virtual void setFrame(const Rect& frame) {
432 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
433 }
434 virtual void setCrop(const Rect& crop) {
435 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
436 }
437 virtual void setVisibleRegionScreen(const Region& reg) {
438 getLayer()->visibleRegionScreen.rects =
439 reinterpret_cast<hwc_rect_t const *>(
440 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
441 }
442 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
443 if (buffer == 0 || buffer->handle == 0) {
444 getLayer()->compositionType = HWC_FRAMEBUFFER;
445 getLayer()->flags |= HWC_SKIP_LAYER;
446 getLayer()->handle = 0;
447 } else {
448 getLayer()->handle = buffer->handle;
449 }
450 }
451};
Jesse Hall5880cc52012-06-05 23:40:32 -0700452// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS
453
454/*
455 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
456 * This implements the HWCLayer side of HWCIterableLayer.
457 */
458class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> {
459public:
460 HWCLayerVersion1(hwc_layer_1_t* layer)
461 : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer) { }
462
463 virtual int32_t getCompositionType() const {
464 return getLayer()->compositionType;
465 }
466 virtual uint32_t getHints() const {
467 return getLayer()->hints;
468 }
Jesse Hallef194142012-06-14 14:45:17 -0700469 virtual int getAndResetReleaseFenceFd() {
470 int fd = getLayer()->releaseFenceFd;
471 getLayer()->releaseFenceFd = -1;
472 return fd;
473 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700474 virtual void setAcquireFenceFd(int fenceFd) {
475 getLayer()->acquireFenceFd = fenceFd;
476 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700477
478 virtual void setDefaultState() {
479 getLayer()->compositionType = HWC_FRAMEBUFFER;
480 getLayer()->hints = 0;
481 getLayer()->flags = HWC_SKIP_LAYER;
482 getLayer()->transform = 0;
483 getLayer()->blending = HWC_BLENDING_NONE;
484 getLayer()->visibleRegionScreen.numRects = 0;
485 getLayer()->visibleRegionScreen.rects = NULL;
486 getLayer()->acquireFenceFd = -1;
487 getLayer()->releaseFenceFd = -1;
488 }
489 virtual void setSkip(bool skip) {
490 if (skip) {
491 getLayer()->flags |= HWC_SKIP_LAYER;
492 } else {
493 getLayer()->flags &= ~HWC_SKIP_LAYER;
494 }
495 }
496 virtual void setBlending(uint32_t blending) {
497 getLayer()->blending = blending;
498 }
499 virtual void setTransform(uint32_t transform) {
500 getLayer()->transform = transform;
501 }
502 virtual void setFrame(const Rect& frame) {
503 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
504 }
505 virtual void setCrop(const Rect& crop) {
506 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
507 }
508 virtual void setVisibleRegionScreen(const Region& reg) {
509 getLayer()->visibleRegionScreen.rects =
510 reinterpret_cast<hwc_rect_t const *>(
511 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
512 }
513 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
514 if (buffer == 0 || buffer->handle == 0) {
515 getLayer()->compositionType = HWC_FRAMEBUFFER;
516 getLayer()->flags |= HWC_SKIP_LAYER;
517 getLayer()->handle = 0;
518 } else {
519 getLayer()->handle = buffer->handle;
520 }
521 }
522};
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700523
524/*
525 * returns an iterator initialized at a given index in the layer list
526 */
527HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) {
528 if (!mList || index > mList->numHwLayers) {
529 return LayerListIterator();
530 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700531 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
532 return LayerListIterator(new HWCLayerVersion1(mList->hwLayers), index);
533 } else {
534 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList;
535 return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index);
536 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700537}
538
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700539/*
540 * returns an iterator on the beginning of the layer list
541 */
542HWComposer::LayerListIterator HWComposer::begin() {
543 return getLayerIterator(0);
544}
545
546/*
547 * returns an iterator on the end of the layer list
548 */
549HWComposer::LayerListIterator HWComposer::end() {
550 return getLayerIterator(getNumLayers());
551}
552
553
554
Mathias Agopian22da60c2011-09-09 00:49:11 -0700555void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
556 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
Mathias Agopian83727852010-09-23 18:13:21 -0700557 if (mHwc && mList) {
558 result.append("Hardware Composer state:\n");
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700559 result.appendFormat(" mDebugForceFakeVSync=%d\n",
560 mDebugForceFakeVSync);
561 result.appendFormat(" numHwLayers=%u, flags=%08x\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700562 mList->numHwLayers, mList->flags);
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700563 result.append(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700564 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n"
565 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
566 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
Mathias Agopian83727852010-09-23 18:13:21 -0700567 for (size_t i=0 ; i<mList->numHwLayers ; i++) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700568 hwc_layer_1_t l;
569 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
570 l = mList->hwLayers[i];
571 } else {
572 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList;
573 *(hwc_layer_t*)&l = list0->hwLayers[i];
574 l.acquireFenceFd = l.releaseFenceFd = -1;
575 }
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700576 const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
577 int32_t format = -1;
578 if (layer->getLayer() != NULL) {
579 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
580 if (buffer != NULL) {
581 format = buffer->getPixelFormat();
582 }
583 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700584 result.appendFormat(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700585 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700586 l.compositionType ? "OVERLAY" : "FB",
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700587 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
Mathias Agopian83727852010-09-23 18:13:21 -0700588 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
Mathias Agopian22da60c2011-09-09 00:49:11 -0700589 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700590 layer->getName().string());
Mathias Agopian83727852010-09-23 18:13:21 -0700591 }
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800592 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700593 if (mHwc && hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_1) && mHwc->dump) {
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800594 mHwc->dump(mHwc, buffer, SIZE);
595 result.append(buffer);
Mathias Agopian83727852010-09-23 18:13:21 -0700596 }
597}
598
Mathias Agopiana350ff92010-08-10 17:14:02 -0700599// ---------------------------------------------------------------------------
Mathias Agopian2965b262012-04-08 15:13:32 -0700600
601HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
602 : mHwc(hwc), mEnabled(false),
603 mNextFakeVSync(0),
604 mRefreshPeriod(hwc.mRefreshPeriod)
605{
606}
607
608void HWComposer::VSyncThread::setEnabled(bool enabled) {
609 Mutex::Autolock _l(mLock);
610 mEnabled = enabled;
611 mCondition.signal();
612}
613
614void HWComposer::VSyncThread::onFirstRef() {
615 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
616}
617
618bool HWComposer::VSyncThread::threadLoop() {
619 { // scope for lock
620 Mutex::Autolock _l(mLock);
621 while (!mEnabled) {
622 mCondition.wait(mLock);
623 }
624 }
625
626 const nsecs_t period = mRefreshPeriod;
627 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
628 nsecs_t next_vsync = mNextFakeVSync;
629 nsecs_t sleep = next_vsync - now;
630 if (sleep < 0) {
631 // we missed, find where the next vsync should be
632 sleep = (period - ((now - next_vsync) % period));
633 next_vsync = now + sleep;
634 }
635 mNextFakeVSync = next_vsync + period;
636
637 struct timespec spec;
638 spec.tv_sec = next_vsync / 1000000000;
639 spec.tv_nsec = next_vsync % 1000000000;
640
641 int err;
642 do {
643 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
644 } while (err<0 && errno == EINTR);
645
646 if (err == 0) {
647 mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
648 }
649
650 return true;
651}
652
653// ---------------------------------------------------------------------------
Mathias Agopiana350ff92010-08-10 17:14:02 -0700654}; // namespace android