Merge "Add a very simple helper function to log slow functions." into jb-mr1-dev
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 33b2f00..877b17c 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -22,10 +22,12 @@
#include <utils/RefBase.h>
#include <utils/String16.h>
#include <utils/Vector.h>
+#include <utils/Flattenable.h>
// ---------------------------------------------------------------------------
namespace android {
+template <typename T> class LightFlattenable;
class Flattenable;
class IBinder;
class IPCThreadState;
@@ -102,6 +104,10 @@
status_t writeWeakBinder(const wp<IBinder>& val);
status_t write(const Flattenable& val);
+ template<typename T>
+ status_t write(const LightFlattenable<T>& val);
+
+
// Place a native_handle into the parcel (the native_handle's file-
// descriptors are dup'ed, so it is safe to delete the native_handle
// when this function returns).
@@ -153,6 +159,9 @@
wp<IBinder> readWeakBinder() const;
status_t read(Flattenable& val) const;
+ template<typename T>
+ status_t read(LightFlattenable<T>& val) const;
+
// Like Parcel.java's readExceptionCode(). Reads the first int32
// off of a Parcel's header, returning 0 or the negative error
// code on exceptions, but also deals with skipping over rich
@@ -267,6 +276,40 @@
// ---------------------------------------------------------------------------
+template<typename T>
+status_t Parcel::write(const LightFlattenable<T>& val) {
+ size_t size(val.getSize());
+ if (!val.isFixedSize()) {
+ status_t err = writeInt32(size);
+ if (err != NO_ERROR) {
+ return err;
+ }
+ }
+ void* buffer = writeInplace(size);
+ return buffer == NULL ? NO_MEMORY :
+ val.flatten(buffer);
+}
+
+template<typename T>
+status_t Parcel::read(LightFlattenable<T>& val) const {
+ size_t size;
+ if (val.isFixedSize()) {
+ size = val.getSize();
+ } else {
+ int32_t s;
+ status_t err = readInt32(&s);
+ if (err != NO_ERROR) {
+ return err;
+ }
+ size = s;
+ }
+ void const* buffer = readInplace(size);
+ return buffer == NULL ? NO_MEMORY :
+ val.unflatten(buffer, size);
+}
+
+// ---------------------------------------------------------------------------
+
inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)
{
parcel.print(to);
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
index e59757a..2af2307 100644
--- a/include/gui/Sensor.h
+++ b/include/gui/Sensor.h
@@ -41,7 +41,7 @@
// ----------------------------------------------------------------------------
-class Sensor : public ASensor, public Flattenable
+class Sensor : public ASensor, public LightFlattenable<Sensor>
{
public:
enum {
@@ -54,7 +54,7 @@
Sensor();
Sensor(struct sensor_t const* hwSensor);
- virtual ~Sensor();
+ ~Sensor();
const String8& getName() const;
const String8& getVendor() const;
@@ -68,13 +68,11 @@
nsecs_t getMinDelayNs() const;
int32_t getVersion() const;
- // Flattenable interface
- virtual size_t getFlattenedSize() const;
- virtual size_t getFdCount() const;
- virtual status_t flatten(void* buffer, size_t size,
- int fds[], size_t count) const;
- virtual status_t unflatten(void const* buffer, size_t size,
- int fds[], size_t count);
+ // LightFlattenable protocol
+ inline bool isFixedSize() const { return false; }
+ size_t getSize() const;
+ status_t flatten(void* buffer) const;
+ status_t unflatten(void const* buffer, size_t size);
private:
String8 mName;
diff --git a/include/ui/Point.h b/include/ui/Point.h
index 1653120..1d7f64d 100644
--- a/include/ui/Point.h
+++ b/include/ui/Point.h
@@ -17,11 +17,12 @@
#ifndef ANDROID_UI_POINT
#define ANDROID_UI_POINT
+#include <utils/Flattenable.h>
#include <utils/TypeHelpers.h>
namespace android {
-class Point
+class Point : public LightFlattenablePod<Point>
{
public:
int x;
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index c2c2675..47d37b6 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_UI_RECT
#define ANDROID_UI_RECT
+#include <utils/Flattenable.h>
#include <utils/TypeHelpers.h>
#include <ui/Point.h>
@@ -24,7 +25,7 @@
namespace android {
-class Rect : public ARect
+class Rect : public ARect, public LightFlattenablePod<Rect>
{
public:
typedef ARect::value_type value_type;
diff --git a/include/ui/Region.h b/include/ui/Region.h
index f242f18..f0819af 100644
--- a/include/ui/Region.h
+++ b/include/ui/Region.h
@@ -23,6 +23,7 @@
#include <utils/Vector.h>
#include <ui/Rect.h>
+#include <utils/Flattenable.h>
namespace android {
// ---------------------------------------------------------------------------
@@ -30,13 +31,12 @@
class String8;
// ---------------------------------------------------------------------------
-class Region
+class Region : public LightFlattenable<Region>
{
public:
Region();
Region(const Region& rhs);
explicit Region(const Rect& rhs);
- explicit Region(const void* buffer);
~Region();
Region& operator = (const Region& rhs);
@@ -122,12 +122,10 @@
// be sorted in Y and X and must not make the region invalid.
void addRectUnchecked(int l, int t, int r, int b);
- // flatten/unflatten a region to/from a raw buffer
- ssize_t write(void* buffer, size_t size) const;
- static ssize_t writeEmpty(void* buffer, size_t size);
-
- ssize_t read(const void* buffer);
- static bool isEmpty(void* buffer);
+ inline bool isFixedSize() const { return false; }
+ size_t getSize() const;
+ status_t flatten(void* buffer) const;
+ status_t unflatten(void const* buffer, size_t size);
void dump(String8& out, const char* what, uint32_t flags=0) const;
void dump(const char* what, uint32_t flags=0) const;
diff --git a/include/utils/Flattenable.h b/include/utils/Flattenable.h
index 852be3b..e40d289 100644
--- a/include/utils/Flattenable.h
+++ b/include/utils/Flattenable.h
@@ -24,6 +24,11 @@
namespace android {
+/*
+ * The Flattenable interface allows an object to serialize itself out
+ * to a byte-buffer and an array of file descriptors.
+ */
+
class Flattenable
{
public:
@@ -56,6 +61,73 @@
};
+/*
+ * LightFlattenable is a protocol allowing object to serialize themselves out
+ * to a byte-buffer.
+ *
+ * LightFlattenable objects must implement this protocol.
+ *
+ * LightFlattenable doesn't require the object to be virtual.
+ */
+template <typename T>
+class LightFlattenable {
+public:
+ // returns whether this object always flatten into the same size.
+ // for efficiency, this should always be inline.
+ inline bool isFixedSize() const;
+
+ // returns size in bytes of the flattened object. must be a constant.
+ inline size_t getSize() const;
+
+ // flattens the object into buffer.
+ inline status_t flatten(void* buffer) const;
+
+ // unflattens the object from buffer of given size.
+ inline status_t unflatten(void const* buffer, size_t size);
+};
+
+template <typename T>
+inline bool LightFlattenable<T>::isFixedSize() const {
+ return static_cast<T const*>(this)->T::isFixedSize();
+}
+template <typename T>
+inline size_t LightFlattenable<T>::getSize() const {
+ return static_cast<T const*>(this)->T::getSize();
+}
+template <typename T>
+inline status_t LightFlattenable<T>::flatten(void* buffer) const {
+ return static_cast<T const*>(this)->T::flatten(buffer);
+}
+template <typename T>
+inline status_t LightFlattenable<T>::unflatten(void const* buffer, size_t size) {
+ return static_cast<T*>(this)->T::unflatten(buffer, size);
+}
+
+/*
+ * LightFlattenablePod is an implementation of the LightFlattenable protocol
+ * for POD (plain-old-data) objects.
+ */
+template <typename T>
+class LightFlattenablePod : public LightFlattenable<T> {
+public:
+ inline bool isFixedSize() const {
+ return true;
+ }
+
+ inline size_t getSize() const {
+ return sizeof(T);
+ }
+ inline status_t flatten(void* buffer) const {
+ *reinterpret_cast<T*>(buffer) = *static_cast<T const*>(this);
+ return NO_ERROR;
+ }
+ inline status_t unflatten(void const* buffer, size_t) {
+ *static_cast<T*>(this) = *reinterpret_cast<T const*>(buffer);
+ return NO_ERROR;
+ }
+};
+
+
}; // namespace android
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
index 7111092..0b76f37 100644
--- a/libs/gui/ISensorServer.cpp
+++ b/libs/gui/ISensorServer.cpp
@@ -55,7 +55,7 @@
int32_t n = reply.readInt32();
v.setCapacity(n);
while (n--) {
- reply.read(static_cast<Flattenable&>(s));
+ reply.read(s);
v.add(s);
}
return v;
@@ -84,7 +84,7 @@
size_t n = v.size();
reply->writeInt32(n);
for (size_t i=0 ; i<n ; i++) {
- reply->write(static_cast<const Flattenable&>(v[i]));
+ reply->write(v[i]);
}
return NO_ERROR;
} break;
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 07f62c4..e2604f8 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -26,14 +26,7 @@
{
status_t err;
- size_t len = transparentRegion.write(NULL, 0);
- err = output.writeInt32(len);
- if (err < NO_ERROR) return err;
-
- void* buf = output.writeInplace(len);
- if (buf == NULL) return NO_MEMORY;
-
- err = transparentRegion.write(buf, len);
+ err = output.write(transparentRegion);
if (err < NO_ERROR) return err;
// NOTE: regions are at the end of the structure
@@ -46,11 +39,8 @@
status_t layer_state_t::read(const Parcel& input)
{
status_t err;
- size_t len = input.readInt32();
- void const* buf = input.readInplace(len);
- if (buf == NULL) return NO_MEMORY;
- err = transparentRegion.read(buf);
+ err = input.read(transparentRegion);
if (err < NO_ERROR) return err;
// NOTE: regions are at the end of the structure
@@ -77,8 +67,8 @@
output.writeInt32(what);
output.writeInt32(layerStack);
output.writeInt32(orientation);
- memcpy(output.writeInplace(sizeof(Rect)), &viewport, sizeof(Rect));
- memcpy(output.writeInplace(sizeof(Rect)), &frame, sizeof(Rect));
+ output.write(viewport);
+ output.write(frame);
return NO_ERROR;
}
@@ -88,8 +78,8 @@
what = input.readInt32();
layerStack = input.readInt32();
orientation = input.readInt32();
- memcpy(&viewport, input.readInplace(sizeof(Rect)), sizeof(Rect));
- memcpy(&frame, input.readInplace(sizeof(Rect)), sizeof(Rect));
+ input.read(viewport);
+ input.read(frame);
return NO_ERROR;
}
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 5cc76b4..c52a88f 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -98,7 +98,7 @@
return mVersion;
}
-size_t Sensor::getFlattenedSize() const
+size_t Sensor::getSize() const
{
return sizeof(int32_t) + ((mName.length() + 3) & ~3) +
sizeof(int32_t) + ((mVendor.length() + 3) & ~3) +
@@ -107,11 +107,6 @@
sizeof(int32_t);
}
-size_t Sensor::getFdCount() const
-{
- return 0;
-}
-
static inline
size_t write(void* buffer, size_t offset, const String8& value) {
memcpy(static_cast<char*>(buffer) + offset, value.string(), value.length());
@@ -130,12 +125,8 @@
return sizeof(int32_t);
}
-status_t Sensor::flatten(void* buffer, size_t size,
- int fds[], size_t count) const
+status_t Sensor::flatten(void* buffer) const
{
- if (size < Sensor::getFlattenedSize())
- return -ENOMEM;
-
size_t offset = 0;
offset += write(buffer, offset, int32_t(mName.length()));
offset += write(buffer, offset, mName);
@@ -149,7 +140,6 @@
offset += write(buffer, offset, mResolution);
offset += write(buffer, offset, mPower);
offset += write(buffer, offset, mMinDelay);
-
return NO_ERROR;
}
@@ -171,8 +161,7 @@
return sizeof(int32_t);
}
-status_t Sensor::unflatten(void const* buffer, size_t size,
- int fds[], size_t count)
+status_t Sensor::unflatten(void const* buffer, size_t size)
{
int32_t len;
size_t offset = 0;
@@ -188,7 +177,6 @@
offset += read(buffer, offset, &mResolution);
offset += read(buffer, offset, &mPower);
offset += read(buffer, offset, &mMinDelay);
-
return NO_ERROR;
}
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 2c7cdf0..a3d8b01 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -66,12 +66,6 @@
{
}
-Region::Region(const void* buffer)
-{
- status_t err = read(buffer);
- ALOGE_IF(err<0, "error %s reading Region from buffer", strerror(err));
-}
-
Region::~Region()
{
}
@@ -561,55 +555,33 @@
// ----------------------------------------------------------------------------
-ssize_t Region::write(void* buffer, size_t size) const
-{
-#if VALIDATE_REGIONS
- validate(*this, "write(buffer)");
-#endif
- const size_t count = mStorage.size();
- const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect);
- if (buffer != NULL) {
- if (sizeNeeded > size) return NO_MEMORY;
- int32_t* const p = static_cast<int32_t*>(buffer);
- *p = count;
- memcpy(p+1, &mBounds, sizeof(Rect));
- if (count) {
- memcpy(p+5, mStorage.array(), count*sizeof(Rect));
+size_t Region::getSize() const {
+ return (mStorage.size() + 1) * sizeof(Rect);
+}
+
+status_t Region::flatten(void* buffer) const {
+ Rect* rects = reinterpret_cast<Rect*>(buffer);
+ *rects++ = mBounds;
+ memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect));
+ return NO_ERROR;
+}
+
+status_t Region::unflatten(void const* buffer, size_t size) {
+ mStorage.clear();
+ if (size >= sizeof(Rect)) {
+ Rect const* rects = reinterpret_cast<Rect const*>(buffer);
+ mBounds = *rects++;
+ size -= sizeof(Rect);
+ size_t count = size / sizeof(Rect);
+ if (count > 0) {
+ ssize_t err = mStorage.insertAt(0, count);
+ if (err < 0) {
+ return status_t(err);
+ }
+ memcpy(mStorage.editArray(), rects, count*sizeof(Rect));
}
}
- return ssize_t(sizeNeeded);
-}
-
-ssize_t Region::read(const void* buffer)
-{
- int32_t const* const p = static_cast<int32_t const*>(buffer);
- const size_t count = *p;
- memcpy(&mBounds, p+1, sizeof(Rect));
- mStorage.clear();
- if (count) {
- mStorage.insertAt(0, count);
- memcpy(mStorage.editArray(), p+5, count*sizeof(Rect));
- }
-#if VALIDATE_REGIONS
- validate(*this, "read(buffer)");
-#endif
- return ssize_t(sizeof(int32_t) + (1+count)*sizeof(Rect));
-}
-
-ssize_t Region::writeEmpty(void* buffer, size_t size)
-{
- const size_t sizeNeeded = sizeof(int32_t) + sizeof(Rect);
- if (sizeNeeded > size) return NO_MEMORY;
- int32_t* const p = static_cast<int32_t*>(buffer);
- memset(p, 0, sizeNeeded);
- return ssize_t(sizeNeeded);
-}
-
-bool Region::isEmpty(void* buffer)
-{
- int32_t const* const p = static_cast<int32_t const*>(buffer);
- Rect const* const b = reinterpret_cast<Rect const *>(p+1);
- return b->isEmpty();
+ return NO_ERROR;
}
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 42aaa24..eea79f8 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -122,7 +122,7 @@
GLES2/gl2.cpp.arm \
#
-LOCAL_SHARED_LIBRARIES += libcutils libEGL
+LOCAL_SHARED_LIBRARIES += libcutils libutils libEGL
LOCAL_LDLIBS := -lpthread -ldl
LOCAL_MODULE:= libGLESv2
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index 4345c2b..b00af1b 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -26,6 +26,9 @@
#include <cutils/log.h>
#include <cutils/properties.h>
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <utils/Trace.h>
+
#include "hooks.h"
#include "egl_impl.h"
@@ -40,6 +43,7 @@
#undef CALL_GL_API_RETURN
#define DEBUG_CALL_GL_API 0
+#define SYSTRACE_CALL_GL_API 0
#if USE_FAST_TLS_KEY
@@ -86,6 +90,13 @@
ALOGD("[" #_api "] 0x%x", status); \
}
+#elif SYSTRACE_CALL_GL_API
+
+ #define CALL_GL_API(_api, ...) \
+ ATRACE_CALL(); \
+ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
+ _c->_api(__VA_ARGS__);
+
#else
#define CALL_GL_API(_api, ...) \
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index cdc8a9f..4cae692 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -79,8 +79,6 @@
mDisplay(EGL_NO_DISPLAY),
mSurface(EGL_NO_SURFACE),
mContext(EGL_NO_CONTEXT),
- mDpiX(), mDpiY(),
- mDensity(),
mDisplayWidth(), mDisplayHeight(), mFormat(),
mFlags(),
mPageFlipCount(),
@@ -103,18 +101,6 @@
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;
}
@@ -137,38 +123,6 @@
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
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 0229dad..e9ba5ff 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -77,9 +77,6 @@
// 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;
@@ -144,9 +141,6 @@
EGLDisplay mDisplay;
EGLSurface mSurface;
EGLContext mContext;
- float mDpiX;
- float mDpiY;
- float mDensity;
int mDisplayWidth;
int mDisplayHeight;
PixelFormat mFormat;
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index f329136..6d33592 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -175,19 +175,6 @@
}
}
-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;
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 95feaa0..bfa500b 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -38,9 +38,6 @@
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();
@@ -52,6 +49,13 @@
// 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
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 49aba52..c9df7a4 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -179,7 +179,8 @@
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),
@@ -238,19 +239,14 @@
}
}
- 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) {
@@ -313,6 +309,14 @@
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) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 52171f3..ac2257e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -36,6 +36,7 @@
struct hwc_composer_device_1;
struct hwc_display_contents_1;
struct hwc_procs;
+struct framebuffer_device_t;
namespace android {
// ---------------------------------------------------------------------------
@@ -62,7 +63,11 @@
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;
@@ -194,6 +199,8 @@
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.
@@ -245,6 +252,8 @@
cb_context* mCBContext;
EventHandler& mEventHandler;
nsecs_t mRefreshPeriod;
+ float mDpiX;
+ float mDpiY;
size_t mVSyncCount;
sp<VSyncThread> mVSyncThread;
bool mDebugForceFakeVSync;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f2b49e8..fbf2873 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -420,7 +420,9 @@
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;
@@ -497,13 +499,48 @@
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);
@@ -1709,6 +1746,8 @@
getHwComposer().acquire();
hw->acquireScreen();
mEventThread->onScreenAcquired();
+ mVisibleRegionsDirty = true;
+ repaintEverything();
}
void SurfaceFlinger::onScreenReleased() {
@@ -1940,15 +1979,13 @@
" 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",