HWComposer.h revision 3eb38cb33e41ce40dd1094bdec850f0fca9f8a53
1/* 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 27#include <utils/StrongPointer.h> 28#include <utils/Vector.h> 29 30extern "C" int clock_nanosleep(clockid_t clock_id, int flags, 31 const struct timespec *request, 32 struct timespec *remain); 33 34namespace android { 35// --------------------------------------------------------------------------- 36 37class String8; 38class SurfaceFlinger; 39class LayerBase; 40 41class HWComposer 42{ 43public: 44 class EventHandler { 45 friend class HWComposer; 46 virtual void onVSyncReceived(int dpy, nsecs_t timestamp) = 0; 47 protected: 48 virtual ~EventHandler() {} 49 }; 50 51 HWComposer(const sp<SurfaceFlinger>& flinger, 52 EventHandler& handler, nsecs_t refreshPeriod); 53 ~HWComposer(); 54 55 status_t initCheck() const; 56 57 // tells the HAL what the framebuffer is 58 void setFrameBuffer(EGLDisplay dpy, EGLSurface sur); 59 60 // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED. 61 status_t createWorkList(size_t numLayers); 62 63 // Asks the HAL what it can do 64 status_t prepare() const; 65 66 // disable hwc until next createWorkList 67 status_t disable(); 68 69 // commits the list 70 status_t commit() const; 71 72 // release hardware resources 73 status_t release() const; 74 75 // get the layer array created by createWorkList() 76 size_t getNumLayers() const; 77 hwc_layer_t* getLayers() const; 78 79 // get number of layers of the given type as updated in prepare(). 80 // type is HWC_OVERLAY or HWC_FRAMEBUFFER 81 size_t getLayerCount(int type) const; 82 83 // 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 ---------------------------------------------------------- 155 void dump(String8& out, char* scratch, size_t SIZE, 156 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const; 157 158private: 159 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 167 struct cb_context { 168 callbacks procs; 169 HWComposer* hwc; 170 }; 171 172 static void hook_invalidate(struct hwc_procs* procs); 173 static void hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp); 174 175 inline void invalidate(); 176 inline void vsync(int dpy, int64_t timestamp); 177 178 sp<SurfaceFlinger> mFlinger; 179 hw_module_t const* mModule; 180 hwc_composer_device_t* mHwc; 181 hwc_layer_list_t* mList; 182 size_t mCapacity; 183 mutable size_t mNumOVLayers; 184 mutable size_t mNumFBLayers; 185 hwc_display_t mDpy; 186 hwc_surface_t mSur; 187 cb_context mCBContext; 188 EventHandler& mEventHandler; 189 nsecs_t mRefreshPeriod; 190 sp<VSyncThread> mVSyncThread; 191}; 192 193 194// --------------------------------------------------------------------------- 195}; // namespace android 196 197#endif // ANDROID_SF_HWCOMPOSER_H 198