blob: 122be5ed018e1d449af86d3fb9b215b754d0a420 [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
34#include <hardware/hardware.h>
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070035#include <hardware/hwcomposer.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070036
37#include <cutils/log.h>
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -070038#include <cutils/properties.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070039
40#include <EGL/egl.h>
41
Mathias Agopian22da60c2011-09-09 00:49:11 -070042#include "LayerBase.h"
Mathias Agopiana350ff92010-08-10 17:14:02 -070043#include "HWComposer.h"
Mathias Agopianc7d14e22011-08-01 16:32:21 -070044#include "SurfaceFlinger.h"
Mathias Agopiana350ff92010-08-10 17:14:02 -070045
46namespace android {
Jesse Hall5880cc52012-06-05 23:40:32 -070047
48// ---------------------------------------------------------------------------
49// Support for HWC_DEVICE_API_VERSION_0_3 and older:
50// Since v0.3 is deprecated and support will be dropped soon, as much as
51// possible the code is written to target v1.0. When using a v0.3 HWC, we
52// allocate v0.3 structures, but assign them to v1.0 pointers. Fields that
53// exist in both versions are located at the same offset, so in most cases we
54// can just use the v1.0 pointer without branches or casts.
55
56#if HWC_REMOVE_DEPRECATED_VERSIONS
57// We need complete types with to satisfy semantic checks, even though the
58// code paths that use these won't get executed at runtime (and will likely be
59// dead-code-eliminated). When we remove the code to support v0.3 we can remove
60// these as well.
61typedef hwc_layer_1_t hwc_layer_t;
62typedef hwc_layer_list_1_t hwc_layer_list_t;
63typedef hwc_composer_device_1_t hwc_composer_device_t;
64#endif
65
66// This function assumes we've already rejected HWC's with lower-than-required
67// versions. Don't use it for the initial "does HWC meet requirements" check!
68static bool hwcHasVersion(const hwc_composer_device_1_t* hwc, uint32_t version) {
69 if (HWC_REMOVE_DEPRECATED_VERSIONS &&
70 version <= HWC_DEVICE_API_VERSION_1_0) {
71 return true;
72 } else {
73 return hwc->common.version >= version;
74 }
75}
76
77static size_t sizeofHwcLayerList(const hwc_composer_device_1_t* hwc,
78 size_t numLayers) {
79 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
80 return sizeof(hwc_layer_list_1_t) + numLayers*sizeof(hwc_layer_1_t);
81 } else {
82 return sizeof(hwc_layer_list_t) + numLayers*sizeof(hwc_layer_t);
83 }
84}
85
Mathias Agopiana350ff92010-08-10 17:14:02 -070086// ---------------------------------------------------------------------------
87
Mathias Agopian3e8b8532012-05-13 20:42:01 -070088struct HWComposer::cb_context {
89 struct callbacks : public hwc_procs_t {
90 // these are here to facilitate the transition when adding
91 // new callbacks (an implementation can check for NULL before
92 // calling a new callback).
93 void (*zero[4])(void);
94 };
95 callbacks procs;
96 HWComposer* hwc;
97};
98
99// ---------------------------------------------------------------------------
100
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700101HWComposer::HWComposer(
102 const sp<SurfaceFlinger>& flinger,
103 EventHandler& handler,
104 nsecs_t refreshPeriod)
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 Agopian3eb38cb2012-04-03 22:09:52 -0700108 mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE),
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700109 mCBContext(new cb_context),
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700110 mEventHandler(handler),
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700111 mRefreshPeriod(refreshPeriod),
112 mVSyncCount(0), mDebugForceFakeVSync(false)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700113{
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700114 char value[PROPERTY_VALUE_MAX];
115 property_get("debug.sf.no_hw_vsync", value, "0");
116 mDebugForceFakeVSync = atoi(value);
117
Mathias Agopian3a778712012-04-09 14:16:47 -0700118 bool needVSyncThread = false;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700119 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
Steve Block32397c12012-01-05 23:22:43 +0000120 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700121 if (err == 0) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700122 err = hwc_open_1(mModule, &mHwc);
Steve Blocke6f43dd2012-01-06 19:20:56 +0000123 ALOGE_IF(err, "%s device failed to initialize (%s)",
Mathias Agopiana350ff92010-08-10 17:14:02 -0700124 HWC_HARDWARE_COMPOSER, strerror(-err));
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700125 if (err == 0) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700126 if (HWC_REMOVE_DEPRECATED_VERSIONS &&
127 mHwc->common.version < HWC_DEVICE_API_VERSION_1_0) {
128 ALOGE("%s device version %#x too old, will not be used",
129 HWC_HARDWARE_COMPOSER, mHwc->common.version);
130 hwc_close_1(mHwc);
131 mHwc = NULL;
132 }
133 }
134
135 if (mHwc) {
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700136 if (mHwc->registerProcs) {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700137 mCBContext->hwc = this;
138 mCBContext->procs.invalidate = &hook_invalidate;
139 mCBContext->procs.vsync = &hook_vsync;
140 mHwc->registerProcs(mHwc, &mCBContext->procs);
141 memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700142 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700143 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_3)) {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700144 if (mDebugForceFakeVSync) {
145 // make sure to turn h/w vsync off in "fake vsync" mode
146 mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0);
147 }
148 } else {
Mathias Agopian3a778712012-04-09 14:16:47 -0700149 needVSyncThread = true;
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700150 }
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700151 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700152 } else {
153 needVSyncThread = true;
154 }
155
156 if (needVSyncThread) {
157 // we don't have VSYNC support, we need to fake it
158 mVSyncThread = new VSyncThread(*this);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700159 }
160}
161
162HWComposer::~HWComposer() {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700163 eventControl(EVENT_VSYNC, 0);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700164 free(mList);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700165 if (mVSyncThread != NULL) {
166 mVSyncThread->requestExitAndWait();
167 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700168 if (mHwc) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700169 hwc_close_1(mHwc);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700170 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700171 delete mCBContext;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700172}
173
174status_t HWComposer::initCheck() const {
175 return mHwc ? NO_ERROR : NO_INIT;
176}
177
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700178void HWComposer::hook_invalidate(struct hwc_procs* procs) {
179 reinterpret_cast<cb_context *>(procs)->hwc->invalidate();
180}
181
Mathias Agopian31d28432012-04-03 16:31:39 -0700182void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) {
183 reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp);
184}
185
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700186void HWComposer::invalidate() {
Mathias Agopiane2c2f922011-10-05 15:00:22 -0700187 mFlinger->repaintEverything();
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700188}
189
Mathias Agopian31d28432012-04-03 16:31:39 -0700190void HWComposer::vsync(int dpy, int64_t timestamp) {
Mathias Agopian2965b262012-04-08 15:13:32 -0700191 ATRACE_INT("VSYNC", ++mVSyncCount&1);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700192 mEventHandler.onVSyncReceived(dpy, timestamp);
193}
194
Mathias Agopian03e40722012-04-26 16:11:59 -0700195void HWComposer::eventControl(int event, int enabled) {
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700196 status_t err = NO_ERROR;
Erik Gilling1a3bf412012-04-06 14:13:32 -0700197 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700198 if (!mDebugForceFakeVSync) {
199 err = mHwc->methods->eventControl(mHwc, event, enabled);
Mathias Agopian03e40722012-04-26 16:11:59 -0700200 // error here should not happen -- not sure what we should
201 // do if it does.
202 ALOGE_IF(err, "eventControl(%d, %d) failed %s",
203 event, enabled, strerror(-err));
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700204 }
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700205 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700206
207 if (err == NO_ERROR && mVSyncThread != NULL) {
208 mVSyncThread->setEnabled(enabled);
209 }
Mathias Agopian31d28432012-04-03 16:31:39 -0700210}
211
Mathias Agopiana350ff92010-08-10 17:14:02 -0700212void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
213 mDpy = (hwc_display_t)dpy;
214 mSur = (hwc_surface_t)sur;
215}
216
217status_t HWComposer::createWorkList(size_t numLayers) {
Mathias Agopian45721772010-08-12 15:03:26 -0700218 if (mHwc) {
219 if (!mList || mCapacity < numLayers) {
220 free(mList);
Jesse Hall5880cc52012-06-05 23:40:32 -0700221 size_t size = sizeofHwcLayerList(mHwc, numLayers);
222 mList = (hwc_layer_list_1_t*)malloc(size);
Mathias Agopian45721772010-08-12 15:03:26 -0700223 mCapacity = numLayers;
224 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700225 mList->flags = HWC_GEOMETRY_CHANGED;
226 mList->numHwLayers = numLayers;
227 }
228 return NO_ERROR;
229}
230
231status_t HWComposer::prepare() const {
232 int err = mHwc->prepare(mHwc, mList);
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700233 if (err == NO_ERROR) {
234 size_t numOVLayers = 0;
235 size_t numFBLayers = 0;
236 size_t count = mList->numHwLayers;
237 for (size_t i=0 ; i<count ; i++) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700238 hwc_layer_1_t* l = NULL;
239 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
240 l = &mList->hwLayers[i];
241 } else {
242 // mList really has hwc_layer_list_t memory layout
243 hwc_layer_list_t* list = (hwc_layer_list_t*)mList;
244 hwc_layer_t* layer = &list->hwLayers[i];
245 l = (hwc_layer_1_t*)layer;
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700246 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700247 if (l->flags & HWC_SKIP_LAYER) {
248 l->compositionType = HWC_FRAMEBUFFER;
249 }
250 switch (l->compositionType) {
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700251 case HWC_OVERLAY:
252 numOVLayers++;
253 break;
254 case HWC_FRAMEBUFFER:
255 numFBLayers++;
256 break;
257 }
258 }
259 mNumOVLayers = numOVLayers;
260 mNumFBLayers = numFBLayers;
261 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700262 return (status_t)err;
263}
264
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700265size_t HWComposer::getLayerCount(int type) const {
266 switch (type) {
267 case HWC_OVERLAY:
268 return mNumOVLayers;
269 case HWC_FRAMEBUFFER:
270 return mNumFBLayers;
271 }
272 return 0;
273}
274
Mathias Agopiana350ff92010-08-10 17:14:02 -0700275status_t HWComposer::commit() const {
276 int err = mHwc->set(mHwc, mDpy, mSur, mList);
Mathias Agopian58959342010-10-07 14:57:04 -0700277 if (mList) {
278 mList->flags &= ~HWC_GEOMETRY_CHANGED;
279 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700280 return (status_t)err;
281}
282
Antti Hatalaf5f27122010-09-09 02:33:05 -0700283status_t HWComposer::release() const {
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700284 if (mHwc) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700285 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_3)) {
Mathias Agopian22ffb112012-04-10 21:04:02 -0700286 mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0);
287 }
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700288 int err = mHwc->set(mHwc, NULL, NULL, NULL);
Colin Cross10fbdb62012-07-12 17:56:34 -0700289 if (err < 0) {
290 return (status_t)err;
291 }
292
293 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
294 if (mHwc->methods && mHwc->methods->blank) {
295 err = mHwc->methods->blank(mHwc, 1);
296 }
297 }
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700298 return (status_t)err;
299 }
300 return NO_ERROR;
301}
302
Colin Cross10fbdb62012-07-12 17:56:34 -0700303status_t HWComposer::acquire() const {
304 if (mHwc) {
305 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
306 if (mHwc->methods && mHwc->methods->blank) {
307 int err = mHwc->methods->blank(mHwc, 0);
308 return (status_t)err;
309 }
310 }
311 }
312
313 return NO_ERROR;
314}
315
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700316status_t HWComposer::disable() {
317 if (mHwc) {
318 free(mList);
319 mList = NULL;
320 int err = mHwc->prepare(mHwc, NULL);
321 return (status_t)err;
322 }
323 return NO_ERROR;
Antti Hatalaf5f27122010-09-09 02:33:05 -0700324}
325
Mathias Agopian45721772010-08-12 15:03:26 -0700326size_t HWComposer::getNumLayers() const {
327 return mList ? mList->numHwLayers : 0;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700328}
329
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700330/*
331 * Helper template to implement a concrete HWCLayer
332 * This holds the pointer to the concrete hwc layer type
333 * and implements the "iterable" side of HWCLayer.
334 */
335template<typename CONCRETE, typename HWCTYPE>
336class Iterable : public HWComposer::HWCLayer {
337protected:
338 HWCTYPE* const mLayerList;
339 HWCTYPE* mCurrentLayer;
340 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
341 inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
342 inline HWCTYPE* getLayer() { return mCurrentLayer; }
343 virtual ~Iterable() { }
344private:
345 // returns a copy of ourselves
346 virtual HWComposer::HWCLayer* dup() {
347 return new CONCRETE( static_cast<const CONCRETE&>(*this) );
348 }
349 virtual status_t setLayer(size_t index) {
350 mCurrentLayer = &mLayerList[index];
351 return NO_ERROR;
352 }
353};
354
Jesse Hall5880cc52012-06-05 23:40:32 -0700355// #if !HWC_REMOVE_DEPRECATED_VERSIONS
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700356/*
357 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
358 * This implements the HWCLayer side of HWCIterableLayer.
359 */
Jesse Hall5880cc52012-06-05 23:40:32 -0700360class HWCLayerVersion0 : public Iterable<HWCLayerVersion0, hwc_layer_t> {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700361public:
Jesse Hall5880cc52012-06-05 23:40:32 -0700362 HWCLayerVersion0(hwc_layer_t* layer)
363 : Iterable<HWCLayerVersion0, hwc_layer_t>(layer) { }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700364
365 virtual int32_t getCompositionType() const {
366 return getLayer()->compositionType;
367 }
368 virtual uint32_t getHints() const {
369 return getLayer()->hints;
370 }
Jesse Hallef194142012-06-14 14:45:17 -0700371 virtual int getAndResetReleaseFenceFd() {
372 // not supported on VERSION_03
373 return -1;
374 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700375 virtual void setAcquireFenceFd(int fenceFd) {
376 if (fenceFd != -1) {
377 ALOGE("HWC 0.x can't handle acquire fences");
378 close(fenceFd);
379 }
380 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700381
382 virtual void setDefaultState() {
383 getLayer()->compositionType = HWC_FRAMEBUFFER;
384 getLayer()->hints = 0;
385 getLayer()->flags = HWC_SKIP_LAYER;
386 getLayer()->transform = 0;
387 getLayer()->blending = HWC_BLENDING_NONE;
388 getLayer()->visibleRegionScreen.numRects = 0;
389 getLayer()->visibleRegionScreen.rects = NULL;
390 }
391 virtual void setSkip(bool skip) {
392 if (skip) {
393 getLayer()->flags |= HWC_SKIP_LAYER;
394 } else {
395 getLayer()->flags &= ~HWC_SKIP_LAYER;
396 }
397 }
398 virtual void setBlending(uint32_t blending) {
399 getLayer()->blending = blending;
400 }
401 virtual void setTransform(uint32_t transform) {
402 getLayer()->transform = transform;
403 }
404 virtual void setFrame(const Rect& frame) {
405 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
406 }
407 virtual void setCrop(const Rect& crop) {
408 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
409 }
410 virtual void setVisibleRegionScreen(const Region& reg) {
411 getLayer()->visibleRegionScreen.rects =
412 reinterpret_cast<hwc_rect_t const *>(
413 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
414 }
415 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
416 if (buffer == 0 || buffer->handle == 0) {
417 getLayer()->compositionType = HWC_FRAMEBUFFER;
418 getLayer()->flags |= HWC_SKIP_LAYER;
419 getLayer()->handle = 0;
420 } else {
421 getLayer()->handle = buffer->handle;
422 }
423 }
424};
Jesse Hall5880cc52012-06-05 23:40:32 -0700425// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS
426
427/*
428 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
429 * This implements the HWCLayer side of HWCIterableLayer.
430 */
431class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> {
432public:
433 HWCLayerVersion1(hwc_layer_1_t* layer)
434 : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer) { }
435
436 virtual int32_t getCompositionType() const {
437 return getLayer()->compositionType;
438 }
439 virtual uint32_t getHints() const {
440 return getLayer()->hints;
441 }
Jesse Hallef194142012-06-14 14:45:17 -0700442 virtual int getAndResetReleaseFenceFd() {
443 int fd = getLayer()->releaseFenceFd;
444 getLayer()->releaseFenceFd = -1;
445 return fd;
446 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700447 virtual void setAcquireFenceFd(int fenceFd) {
448 getLayer()->acquireFenceFd = fenceFd;
449 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700450
451 virtual void setDefaultState() {
452 getLayer()->compositionType = HWC_FRAMEBUFFER;
453 getLayer()->hints = 0;
454 getLayer()->flags = HWC_SKIP_LAYER;
455 getLayer()->transform = 0;
456 getLayer()->blending = HWC_BLENDING_NONE;
457 getLayer()->visibleRegionScreen.numRects = 0;
458 getLayer()->visibleRegionScreen.rects = NULL;
459 getLayer()->acquireFenceFd = -1;
460 getLayer()->releaseFenceFd = -1;
461 }
462 virtual void setSkip(bool skip) {
463 if (skip) {
464 getLayer()->flags |= HWC_SKIP_LAYER;
465 } else {
466 getLayer()->flags &= ~HWC_SKIP_LAYER;
467 }
468 }
469 virtual void setBlending(uint32_t blending) {
470 getLayer()->blending = blending;
471 }
472 virtual void setTransform(uint32_t transform) {
473 getLayer()->transform = transform;
474 }
475 virtual void setFrame(const Rect& frame) {
476 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
477 }
478 virtual void setCrop(const Rect& crop) {
479 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
480 }
481 virtual void setVisibleRegionScreen(const Region& reg) {
482 getLayer()->visibleRegionScreen.rects =
483 reinterpret_cast<hwc_rect_t const *>(
484 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
485 }
486 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
487 if (buffer == 0 || buffer->handle == 0) {
488 getLayer()->compositionType = HWC_FRAMEBUFFER;
489 getLayer()->flags |= HWC_SKIP_LAYER;
490 getLayer()->handle = 0;
491 } else {
492 getLayer()->handle = buffer->handle;
493 }
494 }
495};
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700496
497/*
498 * returns an iterator initialized at a given index in the layer list
499 */
500HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) {
501 if (!mList || index > mList->numHwLayers) {
502 return LayerListIterator();
503 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700504 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
505 return LayerListIterator(new HWCLayerVersion1(mList->hwLayers), index);
506 } else {
507 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList;
508 return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index);
509 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700510}
511
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700512/*
513 * returns an iterator on the beginning of the layer list
514 */
515HWComposer::LayerListIterator HWComposer::begin() {
516 return getLayerIterator(0);
517}
518
519/*
520 * returns an iterator on the end of the layer list
521 */
522HWComposer::LayerListIterator HWComposer::end() {
523 return getLayerIterator(getNumLayers());
524}
525
526
527
Mathias Agopian22da60c2011-09-09 00:49:11 -0700528void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
529 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
Mathias Agopian83727852010-09-23 18:13:21 -0700530 if (mHwc && mList) {
531 result.append("Hardware Composer state:\n");
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700532 result.appendFormat(" mDebugForceFakeVSync=%d\n",
533 mDebugForceFakeVSync);
534 result.appendFormat(" numHwLayers=%u, flags=%08x\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700535 mList->numHwLayers, mList->flags);
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700536 result.append(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700537 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n"
538 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
539 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
Mathias Agopian83727852010-09-23 18:13:21 -0700540 for (size_t i=0 ; i<mList->numHwLayers ; i++) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700541 hwc_layer_1_t l;
542 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
543 l = mList->hwLayers[i];
544 } else {
545 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList;
546 *(hwc_layer_t*)&l = list0->hwLayers[i];
547 l.acquireFenceFd = l.releaseFenceFd = -1;
548 }
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700549 const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
550 int32_t format = -1;
551 if (layer->getLayer() != NULL) {
552 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
553 if (buffer != NULL) {
554 format = buffer->getPixelFormat();
555 }
556 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700557 result.appendFormat(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700558 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700559 l.compositionType ? "OVERLAY" : "FB",
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700560 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
Mathias Agopian83727852010-09-23 18:13:21 -0700561 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
Mathias Agopian22da60c2011-09-09 00:49:11 -0700562 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700563 layer->getName().string());
Mathias Agopian83727852010-09-23 18:13:21 -0700564 }
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800565 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700566 if (mHwc && hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_1) && mHwc->dump) {
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800567 mHwc->dump(mHwc, buffer, SIZE);
568 result.append(buffer);
Mathias Agopian83727852010-09-23 18:13:21 -0700569 }
570}
571
Mathias Agopiana350ff92010-08-10 17:14:02 -0700572// ---------------------------------------------------------------------------
Mathias Agopian2965b262012-04-08 15:13:32 -0700573
574HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
575 : mHwc(hwc), mEnabled(false),
576 mNextFakeVSync(0),
577 mRefreshPeriod(hwc.mRefreshPeriod)
578{
579}
580
581void HWComposer::VSyncThread::setEnabled(bool enabled) {
582 Mutex::Autolock _l(mLock);
583 mEnabled = enabled;
584 mCondition.signal();
585}
586
587void HWComposer::VSyncThread::onFirstRef() {
588 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
589}
590
591bool HWComposer::VSyncThread::threadLoop() {
592 { // scope for lock
593 Mutex::Autolock _l(mLock);
594 while (!mEnabled) {
595 mCondition.wait(mLock);
596 }
597 }
598
599 const nsecs_t period = mRefreshPeriod;
600 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
601 nsecs_t next_vsync = mNextFakeVSync;
602 nsecs_t sleep = next_vsync - now;
603 if (sleep < 0) {
604 // we missed, find where the next vsync should be
605 sleep = (period - ((now - next_vsync) % period));
606 next_vsync = now + sleep;
607 }
608 mNextFakeVSync = next_vsync + period;
609
610 struct timespec spec;
611 spec.tv_sec = next_vsync / 1000000000;
612 spec.tv_nsec = next_vsync % 1000000000;
613
614 int err;
615 do {
616 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
617 } while (err<0 && errno == EINTR);
618
619 if (err == 0) {
620 mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
621 }
622
623 return true;
624}
625
626// ---------------------------------------------------------------------------
Mathias Agopiana350ff92010-08-10 17:14:02 -0700627}; // namespace android