Merge "Initialize new HWC 1.2 fields" into jb-mr1-dev
diff --git a/include/private/ui/RegionHelper.h b/include/private/ui/RegionHelper.h
index 421bdda..8c190dd 100644
--- a/include/private/ui/RegionHelper.h
+++ b/include/private/ui/RegionHelper.h
@@ -26,10 +26,10 @@
template<typename RECT>
class region_operator
{
+public:
typedef typename RECT::value_type TYPE;
static const TYPE max_value = 0x7FFFFFF;
-public:
/*
* Common boolean operations:
* value is computed as 0b101 op 0b110
diff --git a/include/ui/Region.h b/include/ui/Region.h
index 0049fde..43a4450 100644
--- a/include/ui/Region.h
+++ b/include/ui/Region.h
@@ -161,7 +161,8 @@
static void translate(Region& reg, int dx, int dy);
static void translate(Region& dst, const Region& reg, int dx, int dy);
- static bool validate(const Region& reg, const char* name);
+ static bool validate(const Region& reg,
+ const char* name, bool silent = false);
// mStorage is a (manually) sorted array of Rects describing the region
// with an extra Rect as the last element which is set to the
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 94fb1d5..932ef68 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -20,6 +20,7 @@
#include <utils/Log.h>
#include <utils/String8.h>
+#include <utils/CallStack.h>
#include <ui/Rect.h>
#include <ui/Region.h>
@@ -113,10 +114,6 @@
Rect rect(l,t,r,b);
size_t where = mStorage.size() - 1;
mStorage.insertAt(rect, where, 1);
-
-#if VALIDATE_REGIONS
- validate(*this, "addRectUnchecked");
-#endif
}
// ----------------------------------------------------------------------------
@@ -338,47 +335,72 @@
}
};
-bool Region::validate(const Region& reg, const char* name)
+bool Region::validate(const Region& reg, const char* name, bool silent)
{
bool result = true;
const_iterator cur = reg.begin();
const_iterator const tail = reg.end();
- const_iterator prev = cur++;
+ const_iterator prev = cur;
Rect b(*prev);
while (cur != tail) {
- b.left = b.left < cur->left ? b.left : cur->left;
- b.top = b.top < cur->top ? b.top : cur->top;
- b.right = b.right > cur->right ? b.right : cur->right;
- b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom;
- if (cur->top == prev->top) {
- if (cur->bottom != prev->bottom) {
- ALOGE("%s: invalid span %p", name, cur);
+ if (cur->isValid() == false) {
+ ALOGE_IF(!silent, "%s: region contains an invalid Rect", name);
+ result = false;
+ }
+ if (cur->right > region_operator<Rect>::max_value) {
+ ALOGE_IF(!silent, "%s: rect->right > max_value", name);
+ result = false;
+ }
+ if (cur->bottom > region_operator<Rect>::max_value) {
+ ALOGE_IF(!silent, "%s: rect->right > max_value", name);
+ result = false;
+ }
+ if (prev != cur) {
+ b.left = b.left < cur->left ? b.left : cur->left;
+ b.top = b.top < cur->top ? b.top : cur->top;
+ b.right = b.right > cur->right ? b.right : cur->right;
+ b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom;
+ if ((*prev < *cur) == false) {
+ ALOGE_IF(!silent, "%s: region's Rects not sorted", name);
result = false;
- } else if (cur->left < prev->right) {
- ALOGE("%s: spans overlap horizontally prev=%p, cur=%p",
+ }
+ if (cur->top == prev->top) {
+ if (cur->bottom != prev->bottom) {
+ ALOGE_IF(!silent, "%s: invalid span %p", name, cur);
+ result = false;
+ } else if (cur->left < prev->right) {
+ ALOGE_IF(!silent,
+ "%s: spans overlap horizontally prev=%p, cur=%p",
+ name, prev, cur);
+ result = false;
+ }
+ } else if (cur->top < prev->bottom) {
+ ALOGE_IF(!silent,
+ "%s: spans overlap vertically prev=%p, cur=%p",
name, prev, cur);
result = false;
}
- } else if (cur->top < prev->bottom) {
- ALOGE("%s: spans overlap vertically prev=%p, cur=%p",
- name, prev, cur);
- result = false;
+ prev = cur;
}
- prev = cur;
cur++;
}
if (b != reg.getBounds()) {
result = false;
- ALOGE("%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name,
+ ALOGE_IF(!silent,
+ "%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name,
b.left, b.top, b.right, b.bottom,
reg.getBounds().left, reg.getBounds().top,
reg.getBounds().right, reg.getBounds().bottom);
}
if (reg.mStorage.size() == 2) {
- ALOGE("mStorage size is 2, which is never valid");
+ result = false;
+ ALOGE_IF(!silent, "%s: mStorage size is 2, which is never valid", name);
}
- if (result == false) {
+ if (result == false && !silent) {
reg.dump(name);
+ CallStack stack;
+ stack.update();
+ stack.dump("");
}
return result;
}
@@ -564,27 +586,37 @@
}
status_t Region::flatten(void* buffer) const {
+#if VALIDATE_REGIONS
+ validate(*this, "Region::flatten");
+#endif
Rect* rects = reinterpret_cast<Rect*>(buffer);
memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect));
return NO_ERROR;
}
status_t Region::unflatten(void const* buffer, size_t size) {
- mStorage.clear();
+ Region result;
if (size >= sizeof(Rect)) {
Rect const* rects = reinterpret_cast<Rect const*>(buffer);
size_t count = size / sizeof(Rect);
if (count > 0) {
- ssize_t err = mStorage.insertAt(0, count);
+ result.mStorage.clear();
+ ssize_t err = result.mStorage.insertAt(0, count);
if (err < 0) {
return status_t(err);
}
- memcpy(mStorage.editArray(), rects, count*sizeof(Rect));
+ memcpy(result.mStorage.editArray(), rects, count*sizeof(Rect));
}
}
#if VALIDATE_REGIONS
- validate(*this, "Region::unflatten");
+ validate(result, "Region::unflatten");
#endif
+
+ if (!result.validate(result, "Region::unflatten", true)) {
+ ALOGE("Region::unflatten() failed, invalid region");
+ return BAD_VALUE;
+ }
+ mStorage = result.mStorage;
return NO_ERROR;
}
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index eea79f8..31bfcd7 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -57,6 +57,10 @@
LOCAL_CFLAGS += -DMAX_EGL_CACHE_ENTRY_SIZE=$(MAX_EGL_CACHE_ENTRY_SIZE)
endif
+ifneq ($(MAX_EGL_CACHE_KEY_SIZE),)
+ LOCAL_CFLAGS += -DMAX_EGL_CACHE_KEY_SIZE=$(MAX_EGL_CACHE_KEY_SIZE)
+endif
+
ifneq ($(MAX_EGL_CACHE_SIZE),)
LOCAL_CFLAGS += -DMAX_EGL_CACHE_SIZE=$(MAX_EGL_CACHE_SIZE)
endif
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index ed2bef3..72655df 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -29,12 +29,16 @@
#define MAX_EGL_CACHE_ENTRY_SIZE (16 * 1024);
#endif
+#ifndef MAX_EGL_CACHE_KEY_SIZE
+#define MAX_EGL_CACHE_KEY_SIZE (1024);
+#endif
+
#ifndef MAX_EGL_CACHE_SIZE
#define MAX_EGL_CACHE_SIZE (64 * 1024);
#endif
// Cache size limits.
-static const size_t maxKeySize = 1024;
+static const size_t maxKeySize = MAX_EGL_CACHE_KEY_SIZE;
static const size_t maxValueSize = MAX_EGL_CACHE_ENTRY_SIZE;
static const size_t maxTotalSize = MAX_EGL_CACHE_SIZE;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 01ae1c2..6a9cb3e 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -309,7 +309,7 @@
void DisplayDevice::updateGeometryTransform() {
int w = mDisplayWidth;
int h = mDisplayHeight;
- Transform R, S;
+ Transform T, R, S;
if (DisplayDevice::orientationToTransfrom(
mOrientation, w, h, &R) == NO_ERROR) {
dirtyRegion.set(bounds());
@@ -340,20 +340,23 @@
float src_height = viewport.height();
float dst_width = frame.width();
float dst_height = frame.height();
- if (src_width != src_height || dst_width != dst_height) {
+ if (src_width != dst_width || src_height != dst_height) {
float sx = dst_width / src_width;
float sy = dst_height / src_height;
S.set(sx, 0, 0, sy);
}
+
float src_x = viewport.left;
float src_y = viewport.top;
float dst_x = frame.left;
float dst_y = frame.top;
float tx = dst_x - src_x;
float ty = dst_y - src_y;
- S.set(tx, ty);
+ T.set(tx, ty);
- // rotate first, followed by scaling
- mGlobalTransform = S * R;
+ // The viewport and frame are both in the logical orientation, so the
+ // translation is also in that space. So translation must be applied
+ // before rotating from logical to physical orientation.
+ mGlobalTransform = S * R * T;
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 058ba45..6542acd 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -753,27 +753,29 @@
ATRACE_CALL();
mVisibleRegionsDirty = false;
invalidateHwcGeometry();
+
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
+ Region opaqueRegion;
+ Region dirtyRegion;
+ Vector< sp<LayerBase> > layersSortedByZ;
const sp<DisplayDevice>& hw(mDisplays[dpy]);
const Transform& tr(hw->getTransform());
const Rect bounds(hw->getBounds());
+ if (hw->canDraw()) {
+ SurfaceFlinger::computeVisibleRegions(currentLayers,
+ hw->getLayerStack(), dirtyRegion, opaqueRegion);
- Region opaqueRegion;
- Region dirtyRegion;
- computeVisibleRegions(currentLayers,
- hw->getLayerStack(), dirtyRegion, opaqueRegion);
-
- Vector< sp<LayerBase> > layersSortedByZ;
- const size_t count = currentLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
- const Layer::State& s(layer->drawingState());
- if (s.layerStack == hw->getLayerStack()) {
- Region visibleRegion(tr.transform(layer->visibleRegion));
- visibleRegion.andSelf(bounds);
- if (!visibleRegion.isEmpty()) {
- layersSortedByZ.add(layer);
+ const size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ const Layer::State& s(layer->drawingState());
+ if (s.layerStack == hw->getLayerStack()) {
+ Region visibleRegion(tr.transform(layer->visibleRegion));
+ visibleRegion.andSelf(bounds);
+ if (!visibleRegion.isEmpty()) {
+ layersSortedByZ.add(layer);
+ }
}
}
}
@@ -1776,6 +1778,7 @@
mEventThread->onScreenReleased();
hw->releaseScreen();
getHwComposer().release();
+ mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ea03e2d..ffe68c6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -351,8 +351,8 @@
* Compositing
*/
void invalidateHwcGeometry();
- void computeVisibleRegions(const LayerVector& currentLayers,
- uint32_t layerStack,
+ static void computeVisibleRegions(
+ const LayerVector& currentLayers, uint32_t layerStack,
Region& dirtyRegion, Region& opaqueRegion);
void preComposition();