blob: 7c09ab2f02033c8e3d29e27eb4ad3e5d64c4cc4c [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);
289 return (status_t)err;
290 }
291 return NO_ERROR;
292}
293
294status_t HWComposer::disable() {
295 if (mHwc) {
296 free(mList);
297 mList = NULL;
298 int err = mHwc->prepare(mHwc, NULL);
299 return (status_t)err;
300 }
301 return NO_ERROR;
Antti Hatalaf5f27122010-09-09 02:33:05 -0700302}
303
Mathias Agopian45721772010-08-12 15:03:26 -0700304size_t HWComposer::getNumLayers() const {
305 return mList ? mList->numHwLayers : 0;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700306}
307
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700308/*
309 * Helper template to implement a concrete HWCLayer
310 * This holds the pointer to the concrete hwc layer type
311 * and implements the "iterable" side of HWCLayer.
312 */
313template<typename CONCRETE, typename HWCTYPE>
314class Iterable : public HWComposer::HWCLayer {
315protected:
316 HWCTYPE* const mLayerList;
317 HWCTYPE* mCurrentLayer;
318 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
319 inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
320 inline HWCTYPE* getLayer() { return mCurrentLayer; }
321 virtual ~Iterable() { }
322private:
323 // returns a copy of ourselves
324 virtual HWComposer::HWCLayer* dup() {
325 return new CONCRETE( static_cast<const CONCRETE&>(*this) );
326 }
327 virtual status_t setLayer(size_t index) {
328 mCurrentLayer = &mLayerList[index];
329 return NO_ERROR;
330 }
331};
332
Jesse Hall5880cc52012-06-05 23:40:32 -0700333// #if !HWC_REMOVE_DEPRECATED_VERSIONS
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700334/*
335 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
336 * This implements the HWCLayer side of HWCIterableLayer.
337 */
Jesse Hall5880cc52012-06-05 23:40:32 -0700338class HWCLayerVersion0 : public Iterable<HWCLayerVersion0, hwc_layer_t> {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700339public:
Jesse Hall5880cc52012-06-05 23:40:32 -0700340 HWCLayerVersion0(hwc_layer_t* layer)
341 : Iterable<HWCLayerVersion0, hwc_layer_t>(layer) { }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700342
343 virtual int32_t getCompositionType() const {
344 return getLayer()->compositionType;
345 }
346 virtual uint32_t getHints() const {
347 return getLayer()->hints;
348 }
Jesse Hallef194142012-06-14 14:45:17 -0700349 virtual int getAndResetReleaseFenceFd() {
350 // not supported on VERSION_03
351 return -1;
352 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700353
354 virtual void setDefaultState() {
355 getLayer()->compositionType = HWC_FRAMEBUFFER;
356 getLayer()->hints = 0;
357 getLayer()->flags = HWC_SKIP_LAYER;
358 getLayer()->transform = 0;
359 getLayer()->blending = HWC_BLENDING_NONE;
360 getLayer()->visibleRegionScreen.numRects = 0;
361 getLayer()->visibleRegionScreen.rects = NULL;
362 }
363 virtual void setSkip(bool skip) {
364 if (skip) {
365 getLayer()->flags |= HWC_SKIP_LAYER;
366 } else {
367 getLayer()->flags &= ~HWC_SKIP_LAYER;
368 }
369 }
370 virtual void setBlending(uint32_t blending) {
371 getLayer()->blending = blending;
372 }
373 virtual void setTransform(uint32_t transform) {
374 getLayer()->transform = transform;
375 }
376 virtual void setFrame(const Rect& frame) {
377 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
378 }
379 virtual void setCrop(const Rect& crop) {
380 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
381 }
382 virtual void setVisibleRegionScreen(const Region& reg) {
383 getLayer()->visibleRegionScreen.rects =
384 reinterpret_cast<hwc_rect_t const *>(
385 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
386 }
387 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
388 if (buffer == 0 || buffer->handle == 0) {
389 getLayer()->compositionType = HWC_FRAMEBUFFER;
390 getLayer()->flags |= HWC_SKIP_LAYER;
391 getLayer()->handle = 0;
392 } else {
393 getLayer()->handle = buffer->handle;
394 }
395 }
396};
Jesse Hall5880cc52012-06-05 23:40:32 -0700397// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS
398
399/*
400 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
401 * This implements the HWCLayer side of HWCIterableLayer.
402 */
403class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> {
404public:
405 HWCLayerVersion1(hwc_layer_1_t* layer)
406 : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer) { }
407
408 virtual int32_t getCompositionType() const {
409 return getLayer()->compositionType;
410 }
411 virtual uint32_t getHints() const {
412 return getLayer()->hints;
413 }
Jesse Hallef194142012-06-14 14:45:17 -0700414 virtual int getAndResetReleaseFenceFd() {
415 int fd = getLayer()->releaseFenceFd;
416 getLayer()->releaseFenceFd = -1;
417 return fd;
418 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700419
420 virtual void setDefaultState() {
421 getLayer()->compositionType = HWC_FRAMEBUFFER;
422 getLayer()->hints = 0;
423 getLayer()->flags = HWC_SKIP_LAYER;
424 getLayer()->transform = 0;
425 getLayer()->blending = HWC_BLENDING_NONE;
426 getLayer()->visibleRegionScreen.numRects = 0;
427 getLayer()->visibleRegionScreen.rects = NULL;
428 getLayer()->acquireFenceFd = -1;
429 getLayer()->releaseFenceFd = -1;
430 }
431 virtual void setSkip(bool skip) {
432 if (skip) {
433 getLayer()->flags |= HWC_SKIP_LAYER;
434 } else {
435 getLayer()->flags &= ~HWC_SKIP_LAYER;
436 }
437 }
438 virtual void setBlending(uint32_t blending) {
439 getLayer()->blending = blending;
440 }
441 virtual void setTransform(uint32_t transform) {
442 getLayer()->transform = transform;
443 }
444 virtual void setFrame(const Rect& frame) {
445 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
446 }
447 virtual void setCrop(const Rect& crop) {
448 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
449 }
450 virtual void setVisibleRegionScreen(const Region& reg) {
451 getLayer()->visibleRegionScreen.rects =
452 reinterpret_cast<hwc_rect_t const *>(
453 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
454 }
455 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
456 if (buffer == 0 || buffer->handle == 0) {
457 getLayer()->compositionType = HWC_FRAMEBUFFER;
458 getLayer()->flags |= HWC_SKIP_LAYER;
459 getLayer()->handle = 0;
460 } else {
461 getLayer()->handle = buffer->handle;
462 }
463 }
464};
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700465
466/*
467 * returns an iterator initialized at a given index in the layer list
468 */
469HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) {
470 if (!mList || index > mList->numHwLayers) {
471 return LayerListIterator();
472 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700473 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
474 return LayerListIterator(new HWCLayerVersion1(mList->hwLayers), index);
475 } else {
476 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList;
477 return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index);
478 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700479}
480
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700481/*
482 * returns an iterator on the beginning of the layer list
483 */
484HWComposer::LayerListIterator HWComposer::begin() {
485 return getLayerIterator(0);
486}
487
488/*
489 * returns an iterator on the end of the layer list
490 */
491HWComposer::LayerListIterator HWComposer::end() {
492 return getLayerIterator(getNumLayers());
493}
494
495
496
Mathias Agopian22da60c2011-09-09 00:49:11 -0700497void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
498 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
Mathias Agopian83727852010-09-23 18:13:21 -0700499 if (mHwc && mList) {
500 result.append("Hardware Composer state:\n");
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700501 result.appendFormat(" mDebugForceFakeVSync=%d\n",
502 mDebugForceFakeVSync);
503 result.appendFormat(" numHwLayers=%u, flags=%08x\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700504 mList->numHwLayers, mList->flags);
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700505 result.append(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700506 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n"
507 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
508 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
Mathias Agopian83727852010-09-23 18:13:21 -0700509 for (size_t i=0 ; i<mList->numHwLayers ; i++) {
Jesse Hall5880cc52012-06-05 23:40:32 -0700510 hwc_layer_1_t l;
511 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
512 l = mList->hwLayers[i];
513 } else {
514 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList;
515 *(hwc_layer_t*)&l = list0->hwLayers[i];
516 l.acquireFenceFd = l.releaseFenceFd = -1;
517 }
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700518 const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
519 int32_t format = -1;
520 if (layer->getLayer() != NULL) {
521 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
522 if (buffer != NULL) {
523 format = buffer->getPixelFormat();
524 }
525 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700526 result.appendFormat(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700527 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700528 l.compositionType ? "OVERLAY" : "FB",
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700529 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
Mathias Agopian83727852010-09-23 18:13:21 -0700530 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
Mathias Agopian22da60c2011-09-09 00:49:11 -0700531 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700532 layer->getName().string());
Mathias Agopian83727852010-09-23 18:13:21 -0700533 }
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800534 }
Jesse Hall5880cc52012-06-05 23:40:32 -0700535 if (mHwc && hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_1) && mHwc->dump) {
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800536 mHwc->dump(mHwc, buffer, SIZE);
537 result.append(buffer);
Mathias Agopian83727852010-09-23 18:13:21 -0700538 }
539}
540
Mathias Agopiana350ff92010-08-10 17:14:02 -0700541// ---------------------------------------------------------------------------
Mathias Agopian2965b262012-04-08 15:13:32 -0700542
543HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
544 : mHwc(hwc), mEnabled(false),
545 mNextFakeVSync(0),
546 mRefreshPeriod(hwc.mRefreshPeriod)
547{
548}
549
550void HWComposer::VSyncThread::setEnabled(bool enabled) {
551 Mutex::Autolock _l(mLock);
552 mEnabled = enabled;
553 mCondition.signal();
554}
555
556void HWComposer::VSyncThread::onFirstRef() {
557 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
558}
559
560bool HWComposer::VSyncThread::threadLoop() {
561 { // scope for lock
562 Mutex::Autolock _l(mLock);
563 while (!mEnabled) {
564 mCondition.wait(mLock);
565 }
566 }
567
568 const nsecs_t period = mRefreshPeriod;
569 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
570 nsecs_t next_vsync = mNextFakeVSync;
571 nsecs_t sleep = next_vsync - now;
572 if (sleep < 0) {
573 // we missed, find where the next vsync should be
574 sleep = (period - ((now - next_vsync) % period));
575 next_vsync = now + sleep;
576 }
577 mNextFakeVSync = next_vsync + period;
578
579 struct timespec spec;
580 spec.tv_sec = next_vsync / 1000000000;
581 spec.tv_nsec = next_vsync % 1000000000;
582
583 int err;
584 do {
585 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
586 } while (err<0 && errno == EINTR);
587
588 if (err == 0) {
589 mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
590 }
591
592 return true;
593}
594
595// ---------------------------------------------------------------------------
Mathias Agopiana350ff92010-08-10 17:14:02 -0700596}; // namespace android