mDisplay(EGL_NO_DISPLAY),
mSurface(EGL_NO_SURFACE),
mContext(EGL_NO_CONTEXT),
- mDpiX(), mDpiY(),
- mDensity(),
mDisplayWidth(), mDisplayHeight(), mFormat(),
mFlags(),
mPageFlipCount(),
return mFlinger != NULL;
}
-float DisplayDevice::getDpiX() const {
- return mDpiX;
-}
-
-float DisplayDevice::getDpiY() const {
- return mDpiY;
-}
-
-float DisplayDevice::getDensity() const {
- return mDensity;
-}
-
int DisplayDevice::getWidth() const {
return mDisplayWidth;
}
int format;
window->query(window, NATIVE_WINDOW_FORMAT, &format);
- mDpiX = window->xdpi;
- mDpiY = window->ydpi;
-
- // TODO: Not sure if display density should handled by SF any longer
- class Density {
- static int getDensityFromProperty(char const* propName) {
- char property[PROPERTY_VALUE_MAX];
- int density = 0;
- if (property_get(propName, property, NULL) > 0) {
- density = atoi(property);
- }
- return density;
- }
- public:
- static int getEmuDensity() {
- return getDensityFromProperty("qemu.sf.lcd_density"); }
- static int getBuildDensity() {
- return getDensityFromProperty("ro.sf.lcd_density"); }
- };
- // The density of the device is provided by a build property
- mDensity = Density::getBuildDensity() / 160.0f;
- if (mDensity == 0) {
- // the build doesn't provide a density -- this is wrong!
- // use xdpi instead
- ALOGE("ro.sf.lcd_density must be defined as a build property");
- mDensity = mDpiX / 160.0f;
- }
- if (Density::getEmuDensity()) {
- // if "qemu.sf.lcd_density" is specified, it overrides everything
- mDpiX = mDpiY = mDensity = Density::getEmuDensity();
- mDensity /= 160.0f;
- }
/*
* Create our display's surface
// be instantaneous, might involve copying the frame buffer around.
void flip(const Region& dirty) const;
- float getDpiX() const;
- float getDpiY() const;
- float getDensity() const;
int getWidth() const;
int getHeight() const;
PixelFormat getFormat() const;
EGLDisplay mDisplay;
EGLSurface mSurface;
EGLContext mContext;
- float mDpiX;
- float mDpiY;
- float mDensity;
int mDisplayWidth;
int mDisplayHeight;
PixelFormat mFormat;
}
}
-float FramebufferSurface::getRefreshRate() const {
- /* FIXME: REFRESH_RATE is a temporary HACK until we are able to report the
- * refresh rate properly from the HAL. The WindowManagerService now relies
- * on this value.
- */
-#ifndef REFRESH_RATE
- return fbDev->fps;
-#else
- return REFRESH_RATE;
-#warning "refresh rate set via makefile to REFRESH_RATE"
-#endif
-}
-
status_t FramebufferSurface::setUpdateRectangle(const Rect& r)
{
return INVALID_OPERATION;
static sp<FramebufferSurface> create();
- // TODO: this should be coming from HWC
- float getRefreshRate() const;
-
bool isUpdateOnDemand() const { return false; }
status_t setUpdateRectangle(const Rect& updateRect);
status_t compositionComplete();
// BufferQueue. The new buffer is returned in the 'buffer' argument.
status_t nextBuffer(sp<GraphicBuffer>* buffer);
+ // FIXME: currently there are information we can only get from the
+ // FB HAL, and FB HAL can only be instantiated once on some devices.
+ // Eventually this functionality will have to move in HWC or somewhere else.
+ const framebuffer_device_t* getFbHal() const {
+ return fbDev;
+ }
+
private:
FramebufferSurface();
virtual ~FramebufferSurface(); // this class cannot be overloaded
HWComposer::HWComposer(
const sp<SurfaceFlinger>& flinger,
- EventHandler& handler)
+ EventHandler& handler,
+ framebuffer_device_t const* fbDev)
: mFlinger(flinger),
mModule(0), mHwc(0), mCapacity(0),
mNumOVLayers(0), mNumFBLayers(0),
}
}
- if (mRefreshPeriod == 0) {
- // for compatibility, we attempt to get the refresh rate from
- // the FB HAL if we couldn't get it from the HWC HAL.
- hw_module_t const* module;
- if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
- framebuffer_device_t* fbDev;
- int err = framebuffer_open(module, &fbDev);
- if (!err && fbDev) {
- mRefreshPeriod = nsecs_t(1e9 / fbDev->fps);
- framebuffer_close(fbDev);
- }
+
+ if (fbDev) {
+ if (mRefreshPeriod == 0) {
+ mRefreshPeriod = nsecs_t(1e9 / fbDev->fps);
+ ALOGW("getting VSYNC period from fb HAL: %lld", mRefreshPeriod);
}
- ALOGW("getting VSYNC period from fb HAL: %lld", mRefreshPeriod);
+ mDpiX = fbDev->xdpi;
+ mDpiY = fbDev->ydpi;
}
if (mRefreshPeriod == 0) {
return now - ((now - mLastHwVSync) % mRefreshPeriod);
}
+float HWComposer::getDpiX() const {
+ return mDpiX;
+}
+
+float HWComposer::getDpiY() const {
+ return mDpiY;
+}
+
void HWComposer::eventControl(int event, int enabled) {
status_t err = NO_ERROR;
if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
struct hwc_composer_device_1;
struct hwc_display_contents_1;
struct hwc_procs;
+struct framebuffer_device_t;
namespace android {
// ---------------------------------------------------------------------------
MAX_DISPLAYS
};
- HWComposer(const sp<SurfaceFlinger>& flinger, EventHandler& handler);
+ HWComposer(
+ const sp<SurfaceFlinger>& flinger,
+ EventHandler& handler,
+ framebuffer_device_t const* fbDev);
+
~HWComposer();
status_t initCheck() const;
nsecs_t getRefreshPeriod() const;
nsecs_t getRefreshTimestamp() const;
+ float getDpiX() const;
+ float getDpiY() const;
// this class is only used to fake the VSync event on systems that don't
// have it.
cb_context* mCBContext;
EventHandler& mEventHandler;
nsecs_t mRefreshPeriod;
+ float mDpiX;
+ float mDpiY;
size_t mVSyncCount;
sp<VSyncThread> mVSyncThread;
bool mDebugForceFakeVSync;
mEventQueue.setEventThread(mEventThread);
// initialize the H/W composer
- mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));
+ mHwc = new HWComposer(this,
+ *static_cast<HWComposer::EventHandler *>(this),
+ fbs->getFbHal());
// initialize our drawing state
mDrawingState = mCurrentState;
if (uint32_t(dpy) >= 1) {
return BAD_INDEX;
}
+
+ const HWComposer& hwc(getHwComposer());
+ float xdpi = hwc.getDpiX();
+ float ydpi = hwc.getDpiY();
+
+ // TODO: Not sure if display density should handled by SF any longer
+ class Density {
+ static int getDensityFromProperty(char const* propName) {
+ char property[PROPERTY_VALUE_MAX];
+ int density = 0;
+ if (property_get(propName, property, NULL) > 0) {
+ density = atoi(property);
+ }
+ return density;
+ }
+ public:
+ static int getEmuDensity() {
+ return getDensityFromProperty("qemu.sf.lcd_density"); }
+ static int getBuildDensity() {
+ return getDensityFromProperty("ro.sf.lcd_density"); }
+ };
+ // The density of the device is provided by a build property
+ float density = Density::getBuildDensity() / 160.0f;
+ if (density == 0) {
+ // the build doesn't provide a density -- this is wrong!
+ // use xdpi instead
+ ALOGE("ro.sf.lcd_density must be defined as a build property");
+ density = xdpi / 160.0f;
+ }
+ if (Density::getEmuDensity()) {
+ // if "qemu.sf.lcd_density" is specified, it overrides everything
+ xdpi = ydpi = density = Density::getEmuDensity();
+ density /= 160.0f;
+ }
+
sp<const DisplayDevice> hw(getDefaultDisplayDevice());
info->w = hw->getWidth();
info->h = hw->getHeight();
- info->xdpi = hw->getDpiX();
- info->ydpi = hw->getDpiY();
- info->fps = float(1e9 / getHwComposer().getRefreshPeriod());
- info->density = hw->getDensity();
+ info->xdpi = xdpi;
+ info->ydpi = ydpi;
+ info->fps = float(1e9 / hwc.getRefreshPeriod());
+ info->density = density;
info->orientation = hw->getOrientation();
// TODO: this needs to go away (currently needed only by webkit)
getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
" transaction-flags : %08x\n"
" refresh-rate : %f fps\n"
" x-dpi : %f\n"
- " y-dpi : %f\n"
- " density : %f\n",
+ " y-dpi : %f\n",
mLastSwapBufferTime/1000.0,
mLastTransactionTime/1000.0,
mTransactionFlags,
1e9 / hwc.getRefreshPeriod(),
- hw->getDpiX(),
- hw->getDpiY(),
- hw->getDensity());
+ hwc.getDpiX(),
+ hwc.getDpiY());
result.append(buffer);
snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n",