blob: ce63ee7194be0642353f2ba64c30e0451de46dca [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
Mathias Agopiana350ff92010-08-10 17:14:02 -070019#include <stdint.h>
Mathias Agopianf1352df2010-08-11 17:31:33 -070020#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070023#include <sys/types.h>
24
25#include <utils/Errors.h>
Mathias Agopian83727852010-09-23 18:13:21 -070026#include <utils/String8.h>
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070027#include <utils/Thread.h>
Mathias Agopian2965b262012-04-08 15:13:32 -070028#include <utils/Trace.h>
Mathias Agopian22da60c2011-09-09 00:49:11 -070029#include <utils/Vector.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070030
31#include <hardware/hardware.h>
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070032#include <hardware/hwcomposer.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070033
34#include <cutils/log.h>
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -070035#include <cutils/properties.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070036
37#include <EGL/egl.h>
38
Mathias Agopian22da60c2011-09-09 00:49:11 -070039#include "LayerBase.h"
Mathias Agopiana350ff92010-08-10 17:14:02 -070040#include "HWComposer.h"
Mathias Agopianc7d14e22011-08-01 16:32:21 -070041#include "SurfaceFlinger.h"
Mathias Agopiana350ff92010-08-10 17:14:02 -070042
43namespace android {
44// ---------------------------------------------------------------------------
45
Mathias Agopian3e8b8532012-05-13 20:42:01 -070046struct HWComposer::cb_context {
47 struct callbacks : public hwc_procs_t {
48 // these are here to facilitate the transition when adding
49 // new callbacks (an implementation can check for NULL before
50 // calling a new callback).
51 void (*zero[4])(void);
52 };
53 callbacks procs;
54 HWComposer* hwc;
55};
56
57// ---------------------------------------------------------------------------
58
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070059HWComposer::HWComposer(
60 const sp<SurfaceFlinger>& flinger,
61 EventHandler& handler,
62 nsecs_t refreshPeriod)
Mathias Agopianc7d14e22011-08-01 16:32:21 -070063 : mFlinger(flinger),
64 mModule(0), mHwc(0), mList(0), mCapacity(0),
Mathias Agopian9c6e2972011-09-20 17:21:56 -070065 mNumOVLayers(0), mNumFBLayers(0),
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070066 mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE),
Mathias Agopian3e8b8532012-05-13 20:42:01 -070067 mCBContext(new cb_context),
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070068 mEventHandler(handler),
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -070069 mRefreshPeriod(refreshPeriod),
70 mVSyncCount(0), mDebugForceFakeVSync(false)
Mathias Agopiana350ff92010-08-10 17:14:02 -070071{
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -070072 char value[PROPERTY_VALUE_MAX];
73 property_get("debug.sf.no_hw_vsync", value, "0");
74 mDebugForceFakeVSync = atoi(value);
75
Mathias Agopian3a778712012-04-09 14:16:47 -070076 bool needVSyncThread = false;
Mathias Agopiana350ff92010-08-10 17:14:02 -070077 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
Steve Block32397c12012-01-05 23:22:43 +000078 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
Mathias Agopiana350ff92010-08-10 17:14:02 -070079 if (err == 0) {
80 err = hwc_open(mModule, &mHwc);
Steve Blocke6f43dd2012-01-06 19:20:56 +000081 ALOGE_IF(err, "%s device failed to initialize (%s)",
Mathias Agopiana350ff92010-08-10 17:14:02 -070082 HWC_HARDWARE_COMPOSER, strerror(-err));
Mathias Agopianc7d14e22011-08-01 16:32:21 -070083 if (err == 0) {
84 if (mHwc->registerProcs) {
Mathias Agopian3e8b8532012-05-13 20:42:01 -070085 mCBContext->hwc = this;
86 mCBContext->procs.invalidate = &hook_invalidate;
87 mCBContext->procs.vsync = &hook_vsync;
88 mHwc->registerProcs(mHwc, &mCBContext->procs);
89 memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
Mathias Agopianc7d14e22011-08-01 16:32:21 -070090 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -070091 if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
92 if (mDebugForceFakeVSync) {
93 // make sure to turn h/w vsync off in "fake vsync" mode
94 mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0);
95 }
96 } else {
Mathias Agopian3a778712012-04-09 14:16:47 -070097 needVSyncThread = true;
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070098 }
Mathias Agopianc7d14e22011-08-01 16:32:21 -070099 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700100 } else {
101 needVSyncThread = true;
102 }
103
104 if (needVSyncThread) {
105 // we don't have VSYNC support, we need to fake it
106 mVSyncThread = new VSyncThread(*this);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700107 }
108}
109
110HWComposer::~HWComposer() {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700111 eventControl(EVENT_VSYNC, 0);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700112 free(mList);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700113 if (mVSyncThread != NULL) {
114 mVSyncThread->requestExitAndWait();
115 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700116 if (mHwc) {
117 hwc_close(mHwc);
118 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700119 delete mCBContext;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700120}
121
122status_t HWComposer::initCheck() const {
123 return mHwc ? NO_ERROR : NO_INIT;
124}
125
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700126void HWComposer::hook_invalidate(struct hwc_procs* procs) {
127 reinterpret_cast<cb_context *>(procs)->hwc->invalidate();
128}
129
Mathias Agopian31d28432012-04-03 16:31:39 -0700130void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) {
131 reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp);
132}
133
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700134void HWComposer::invalidate() {
Mathias Agopiane2c2f922011-10-05 15:00:22 -0700135 mFlinger->repaintEverything();
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700136}
137
Mathias Agopian31d28432012-04-03 16:31:39 -0700138void HWComposer::vsync(int dpy, int64_t timestamp) {
Mathias Agopian2965b262012-04-08 15:13:32 -0700139 ATRACE_INT("VSYNC", ++mVSyncCount&1);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700140 mEventHandler.onVSyncReceived(dpy, timestamp);
141}
142
Mathias Agopian03e40722012-04-26 16:11:59 -0700143void HWComposer::eventControl(int event, int enabled) {
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700144 status_t err = NO_ERROR;
Erik Gilling1a3bf412012-04-06 14:13:32 -0700145 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700146 if (!mDebugForceFakeVSync) {
147 err = mHwc->methods->eventControl(mHwc, event, enabled);
Mathias Agopian03e40722012-04-26 16:11:59 -0700148 // error here should not happen -- not sure what we should
149 // do if it does.
150 ALOGE_IF(err, "eventControl(%d, %d) failed %s",
151 event, enabled, strerror(-err));
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700152 }
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700153 }
Mathias Agopian3a778712012-04-09 14:16:47 -0700154
155 if (err == NO_ERROR && mVSyncThread != NULL) {
156 mVSyncThread->setEnabled(enabled);
157 }
Mathias Agopian31d28432012-04-03 16:31:39 -0700158}
159
Mathias Agopiana350ff92010-08-10 17:14:02 -0700160void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
161 mDpy = (hwc_display_t)dpy;
162 mSur = (hwc_surface_t)sur;
163}
164
165status_t HWComposer::createWorkList(size_t numLayers) {
Mathias Agopian45721772010-08-12 15:03:26 -0700166 if (mHwc) {
167 if (!mList || mCapacity < numLayers) {
168 free(mList);
169 size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
170 mList = (hwc_layer_list_t*)malloc(size);
171 mCapacity = numLayers;
172 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700173 mList->flags = HWC_GEOMETRY_CHANGED;
174 mList->numHwLayers = numLayers;
175 }
176 return NO_ERROR;
177}
178
179status_t HWComposer::prepare() const {
180 int err = mHwc->prepare(mHwc, mList);
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700181 if (err == NO_ERROR) {
182 size_t numOVLayers = 0;
183 size_t numFBLayers = 0;
184 size_t count = mList->numHwLayers;
185 for (size_t i=0 ; i<count ; i++) {
186 hwc_layer& l(mList->hwLayers[i]);
187 if (l.flags & HWC_SKIP_LAYER) {
188 l.compositionType = HWC_FRAMEBUFFER;
189 }
190 switch (l.compositionType) {
191 case HWC_OVERLAY:
192 numOVLayers++;
193 break;
194 case HWC_FRAMEBUFFER:
195 numFBLayers++;
196 break;
197 }
198 }
199 mNumOVLayers = numOVLayers;
200 mNumFBLayers = numFBLayers;
201 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700202 return (status_t)err;
203}
204
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700205size_t HWComposer::getLayerCount(int type) const {
206 switch (type) {
207 case HWC_OVERLAY:
208 return mNumOVLayers;
209 case HWC_FRAMEBUFFER:
210 return mNumFBLayers;
211 }
212 return 0;
213}
214
Mathias Agopiana350ff92010-08-10 17:14:02 -0700215status_t HWComposer::commit() const {
216 int err = mHwc->set(mHwc, mDpy, mSur, mList);
Mathias Agopian58959342010-10-07 14:57:04 -0700217 if (mList) {
218 mList->flags &= ~HWC_GEOMETRY_CHANGED;
219 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700220 return (status_t)err;
221}
222
Antti Hatalaf5f27122010-09-09 02:33:05 -0700223status_t HWComposer::release() const {
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700224 if (mHwc) {
Mathias Agopian22ffb112012-04-10 21:04:02 -0700225 if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
226 mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0);
227 }
Mathias Agopian7ee4cd52011-09-02 12:22:39 -0700228 int err = mHwc->set(mHwc, NULL, NULL, NULL);
229 return (status_t)err;
230 }
231 return NO_ERROR;
232}
233
234status_t HWComposer::disable() {
235 if (mHwc) {
236 free(mList);
237 mList = NULL;
238 int err = mHwc->prepare(mHwc, NULL);
239 return (status_t)err;
240 }
241 return NO_ERROR;
Antti Hatalaf5f27122010-09-09 02:33:05 -0700242}
243
Mathias Agopian45721772010-08-12 15:03:26 -0700244size_t HWComposer::getNumLayers() const {
245 return mList ? mList->numHwLayers : 0;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700246}
247
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700248/*
249 * Helper template to implement a concrete HWCLayer
250 * This holds the pointer to the concrete hwc layer type
251 * and implements the "iterable" side of HWCLayer.
252 */
253template<typename CONCRETE, typename HWCTYPE>
254class Iterable : public HWComposer::HWCLayer {
255protected:
256 HWCTYPE* const mLayerList;
257 HWCTYPE* mCurrentLayer;
258 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
259 inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
260 inline HWCTYPE* getLayer() { return mCurrentLayer; }
261 virtual ~Iterable() { }
262private:
263 // returns a copy of ourselves
264 virtual HWComposer::HWCLayer* dup() {
265 return new CONCRETE( static_cast<const CONCRETE&>(*this) );
266 }
267 virtual status_t setLayer(size_t index) {
268 mCurrentLayer = &mLayerList[index];
269 return NO_ERROR;
270 }
271};
272
273/*
274 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
275 * This implements the HWCLayer side of HWCIterableLayer.
276 */
277class HWCLayerVersion03 : public Iterable<HWCLayerVersion03, hwc_layer_t> {
278public:
279 HWCLayerVersion03(hwc_layer_t* layer)
280 : Iterable<HWCLayerVersion03, hwc_layer_t>(layer) { }
281
282 virtual int32_t getCompositionType() const {
283 return getLayer()->compositionType;
284 }
285 virtual uint32_t getHints() const {
286 return getLayer()->hints;
287 }
288
289 virtual void setDefaultState() {
290 getLayer()->compositionType = HWC_FRAMEBUFFER;
291 getLayer()->hints = 0;
292 getLayer()->flags = HWC_SKIP_LAYER;
293 getLayer()->transform = 0;
294 getLayer()->blending = HWC_BLENDING_NONE;
295 getLayer()->visibleRegionScreen.numRects = 0;
296 getLayer()->visibleRegionScreen.rects = NULL;
297 }
298 virtual void setSkip(bool skip) {
299 if (skip) {
300 getLayer()->flags |= HWC_SKIP_LAYER;
301 } else {
302 getLayer()->flags &= ~HWC_SKIP_LAYER;
303 }
304 }
305 virtual void setBlending(uint32_t blending) {
306 getLayer()->blending = blending;
307 }
308 virtual void setTransform(uint32_t transform) {
309 getLayer()->transform = transform;
310 }
311 virtual void setFrame(const Rect& frame) {
312 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
313 }
314 virtual void setCrop(const Rect& crop) {
315 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
316 }
317 virtual void setVisibleRegionScreen(const Region& reg) {
318 getLayer()->visibleRegionScreen.rects =
319 reinterpret_cast<hwc_rect_t const *>(
320 reg.getArray(&getLayer()->visibleRegionScreen.numRects));
321 }
322 virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
323 if (buffer == 0 || buffer->handle == 0) {
324 getLayer()->compositionType = HWC_FRAMEBUFFER;
325 getLayer()->flags |= HWC_SKIP_LAYER;
326 getLayer()->handle = 0;
327 } else {
328 getLayer()->handle = buffer->handle;
329 }
330 }
331};
332
333/*
334 * returns an iterator initialized at a given index in the layer list
335 */
336HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) {
337 if (!mList || index > mList->numHwLayers) {
338 return LayerListIterator();
339 }
340 return LayerListIterator(new HWCLayerVersion03(mList->hwLayers), index);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700341}
342
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700343/*
344 * returns an iterator on the beginning of the layer list
345 */
346HWComposer::LayerListIterator HWComposer::begin() {
347 return getLayerIterator(0);
348}
349
350/*
351 * returns an iterator on the end of the layer list
352 */
353HWComposer::LayerListIterator HWComposer::end() {
354 return getLayerIterator(getNumLayers());
355}
356
357
358
Mathias Agopian22da60c2011-09-09 00:49:11 -0700359void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
360 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
Mathias Agopian83727852010-09-23 18:13:21 -0700361 if (mHwc && mList) {
362 result.append("Hardware Composer state:\n");
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700363 result.appendFormat(" mDebugForceFakeVSync=%d\n",
364 mDebugForceFakeVSync);
365 result.appendFormat(" numHwLayers=%u, flags=%08x\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700366 mList->numHwLayers, mList->flags);
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700367 result.append(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700368 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n"
369 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
370 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
Mathias Agopian83727852010-09-23 18:13:21 -0700371 for (size_t i=0 ; i<mList->numHwLayers ; i++) {
372 const hwc_layer_t& l(mList->hwLayers[i]);
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700373 const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
374 int32_t format = -1;
375 if (layer->getLayer() != NULL) {
376 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
377 if (buffer != NULL) {
378 format = buffer->getPixelFormat();
379 }
380 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700381 result.appendFormat(
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700382 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
Mathias Agopian83727852010-09-23 18:13:21 -0700383 l.compositionType ? "OVERLAY" : "FB",
Mathias Agopianaebac5f2011-09-29 18:07:08 -0700384 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
Mathias Agopian83727852010-09-23 18:13:21 -0700385 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
Mathias Agopian22da60c2011-09-09 00:49:11 -0700386 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
Mathias Agopianfb4d5d52011-09-20 15:13:14 -0700387 layer->getName().string());
Mathias Agopian83727852010-09-23 18:13:21 -0700388 }
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800389 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700390 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_1 && mHwc->dump) {
Erik Gilling1d21a9c2010-12-01 16:38:01 -0800391 mHwc->dump(mHwc, buffer, SIZE);
392 result.append(buffer);
Mathias Agopian83727852010-09-23 18:13:21 -0700393 }
394}
395
Mathias Agopiana350ff92010-08-10 17:14:02 -0700396// ---------------------------------------------------------------------------
Mathias Agopian2965b262012-04-08 15:13:32 -0700397
398HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
399 : mHwc(hwc), mEnabled(false),
400 mNextFakeVSync(0),
401 mRefreshPeriod(hwc.mRefreshPeriod)
402{
403}
404
405void HWComposer::VSyncThread::setEnabled(bool enabled) {
406 Mutex::Autolock _l(mLock);
407 mEnabled = enabled;
408 mCondition.signal();
409}
410
411void HWComposer::VSyncThread::onFirstRef() {
412 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
413}
414
415bool HWComposer::VSyncThread::threadLoop() {
416 { // scope for lock
417 Mutex::Autolock _l(mLock);
418 while (!mEnabled) {
419 mCondition.wait(mLock);
420 }
421 }
422
423 const nsecs_t period = mRefreshPeriod;
424 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
425 nsecs_t next_vsync = mNextFakeVSync;
426 nsecs_t sleep = next_vsync - now;
427 if (sleep < 0) {
428 // we missed, find where the next vsync should be
429 sleep = (period - ((now - next_vsync) % period));
430 next_vsync = now + sleep;
431 }
432 mNextFakeVSync = next_vsync + period;
433
434 struct timespec spec;
435 spec.tv_sec = next_vsync / 1000000000;
436 spec.tv_nsec = next_vsync % 1000000000;
437
438 int err;
439 do {
440 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
441 } while (err<0 && errno == EINTR);
442
443 if (err == 0) {
444 mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
445 }
446
447 return true;
448}
449
450// ---------------------------------------------------------------------------
Mathias Agopiana350ff92010-08-10 17:14:02 -0700451}; // namespace android