blob: 60a636748b16dab3b7f0fb1d240454e5374ea88f [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
17#ifndef ANDROID_SF_HWCOMPOSER_H
18#define ANDROID_SF_HWCOMPOSER_H
19
20#include <stdint.h>
21#include <sys/types.h>
22
23#include <EGL/egl.h>
24
25#include <hardware/hwcomposer.h>
26
Mathias Agopianc7d14e22011-08-01 16:32:21 -070027#include <utils/StrongPointer.h>
Mathias Agopian22da60c2011-09-09 00:49:11 -070028#include <utils/Vector.h>
Mathias Agopianc7d14e22011-08-01 16:32:21 -070029
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070030extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
31 const struct timespec *request,
32 struct timespec *remain);
33
Mathias Agopiana350ff92010-08-10 17:14:02 -070034namespace android {
35// ---------------------------------------------------------------------------
36
Mathias Agopian83727852010-09-23 18:13:21 -070037class String8;
Mathias Agopianc7d14e22011-08-01 16:32:21 -070038class SurfaceFlinger;
Mathias Agopian22da60c2011-09-09 00:49:11 -070039class LayerBase;
Mathias Agopian83727852010-09-23 18:13:21 -070040
Mathias Agopiana350ff92010-08-10 17:14:02 -070041class HWComposer
42{
43public:
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070044 class EventHandler {
45 friend class HWComposer;
46 virtual void onVSyncReceived(int dpy, nsecs_t timestamp) = 0;
47 protected:
48 virtual ~EventHandler() {}
49 };
Mathias Agopiana350ff92010-08-10 17:14:02 -070050
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070051 HWComposer(const sp<SurfaceFlinger>& flinger,
52 EventHandler& handler, nsecs_t refreshPeriod);
Mathias Agopiana350ff92010-08-10 17:14:02 -070053 ~HWComposer();
54
55 status_t initCheck() const;
56
57 // tells the HAL what the framebuffer is
58 void setFrameBuffer(EGLDisplay dpy, EGLSurface sur);
59
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070060 // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
Mathias Agopiana350ff92010-08-10 17:14:02 -070061 status_t createWorkList(size_t numLayers);
62
63 // Asks the HAL what it can do
64 status_t prepare() const;
65
Mathias Agopian7ee4cd52011-09-02 12:22:39 -070066 // disable hwc until next createWorkList
67 status_t disable();
68
Mathias Agopiana350ff92010-08-10 17:14:02 -070069 // commits the list
70 status_t commit() const;
71
Antti Hatalaf5f27122010-09-09 02:33:05 -070072 // release hardware resources
73 status_t release() const;
Mathias Agopiana350ff92010-08-10 17:14:02 -070074
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070075 // get the layer array created by createWorkList()
Mathias Agopian45721772010-08-12 15:03:26 -070076 size_t getNumLayers() const;
77 hwc_layer_t* getLayers() const;
Mathias Agopiana350ff92010-08-10 17:14:02 -070078
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070079 // get number of layers of the given type as updated in prepare().
80 // type is HWC_OVERLAY or HWC_FRAMEBUFFER
Mathias Agopian9c6e2972011-09-20 17:21:56 -070081 size_t getLayerCount(int type) const;
82
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070083 // Events handling ---------------------------------------------------------
84
85 enum {
86 EVENT_VSYNC = HWC_EVENT_VSYNC
87 };
88
89 status_t eventControl(int event, int enabled);
90
91 // this class is only used to fake the VSync event on systems that don't
92 // have it.
93 class VSyncThread : public Thread {
94 HWComposer& mHwc;
95 mutable Mutex mLock;
96 Condition mCondition;
97 bool mEnabled;
98 mutable nsecs_t mNextFakeVSync;
99 nsecs_t mRefreshPeriod;
100
101 virtual void onFirstRef() {
102 run("VSyncThread",
103 PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
104 }
105
106 virtual bool threadLoop() {
107 { // scope for lock
108 Mutex::Autolock _l(mLock);
109 while (!mEnabled) {
110 mCondition.wait(mLock);
111 }
112 }
113
114 const nsecs_t period = mRefreshPeriod;
115 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
116 nsecs_t next_vsync = mNextFakeVSync;
117 nsecs_t sleep = next_vsync - now;
118 if (sleep < 0) {
119 // we missed, find where the next vsync should be
120 sleep = (period - ((now - next_vsync) % period));
121 next_vsync = now + sleep;
122 }
123 mNextFakeVSync = next_vsync + period;
124
125 struct timespec spec;
126 spec.tv_sec = next_vsync / 1000000000;
127 spec.tv_nsec = next_vsync % 1000000000;
128
129 // NOTE: EINTR can happen with clock_nanosleep(), in case of
130 // any error (including EINTR) we go through the condition's
131 // test -- this is always correct and easy.
132 if (::clock_nanosleep(CLOCK_MONOTONIC,
133 TIMER_ABSTIME, &spec, NULL) == 0) {
134 mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
135 }
136 return true;
137 }
138
139 public:
140 VSyncThread(HWComposer& hwc) :
141 mHwc(hwc), mEnabled(false),
142 mNextFakeVSync(0),
143 mRefreshPeriod(hwc.mRefreshPeriod) {
144 }
145 void setEnabled(bool enabled) {
146 Mutex::Autolock _l(mLock);
147 mEnabled = enabled;
148 mCondition.signal();
149 }
150 };
151
152 friend class VSyncThread;
153
154 // for debugging ----------------------------------------------------------
Mathias Agopian22da60c2011-09-09 00:49:11 -0700155 void dump(String8& out, char* scratch, size_t SIZE,
156 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const;
Mathias Agopian83727852010-09-23 18:13:21 -0700157
Mathias Agopiana350ff92010-08-10 17:14:02 -0700158private:
Mathias Agopian31d28432012-04-03 16:31:39 -0700159
160 struct callbacks : public hwc_procs_t {
161 // these are here to facilitate the transition when adding
162 // new callbacks (an implementation can check for NULL before
163 // calling a new callback).
164 void (*zero[4])(void);
165 };
166
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700167 struct cb_context {
Mathias Agopian31d28432012-04-03 16:31:39 -0700168 callbacks procs;
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700169 HWComposer* hwc;
170 };
Mathias Agopian31d28432012-04-03 16:31:39 -0700171
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700172 static void hook_invalidate(struct hwc_procs* procs);
Mathias Agopian31d28432012-04-03 16:31:39 -0700173 static void hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp);
174
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700175 inline void invalidate();
176 inline void vsync(int dpy, int64_t timestamp);
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700177
178 sp<SurfaceFlinger> mFlinger;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700179 hw_module_t const* mModule;
180 hwc_composer_device_t* mHwc;
181 hwc_layer_list_t* mList;
Mathias Agopian45721772010-08-12 15:03:26 -0700182 size_t mCapacity;
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700183 mutable size_t mNumOVLayers;
184 mutable size_t mNumFBLayers;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700185 hwc_display_t mDpy;
186 hwc_surface_t mSur;
Mathias Agopianc7d14e22011-08-01 16:32:21 -0700187 cb_context mCBContext;
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700188 EventHandler& mEventHandler;
189 nsecs_t mRefreshPeriod;
190 sp<VSyncThread> mVSyncThread;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700191};
192
193
194// ---------------------------------------------------------------------------
195}; // namespace android
196
197#endif // ANDROID_SF_HWCOMPOSER_H