summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathias Agopian <mathias@google.com> 2013-02-26 16:54:05 -0800
committer Mathias Agopian <mathias@google.com> 2013-02-28 18:43:04 -0800
commitf5f714aa188884098aaecbe39d0bc61b40311c0d (patch)
tree65cfd7c5d63d4bdf9bf0c8d83e419324dd2770b2
parent5219a06d61ac4517506500363c5e8a5972dd7ac9 (diff)
apply the projection's viewport to the visibleregion passed to hwc
each desplay's projection's viewport essentially clips each layer, so this should be reflected in the visibleregion passed to h/w composer. DisplayDevice getViewport and getFrame are now guaranteed to return valid Rects. Change-Id: I4c25f34fb26af10179eb26d429ca6c384c671e91
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp125
-rw-r--r--services/surfaceflinger/DisplayDevice.h6
-rw-r--r--services/surfaceflinger/LayerBase.cpp5
3 files changed, 68 insertions, 68 deletions
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 9466944490..f9cc341811 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -287,7 +287,8 @@ void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& lay
mSecureLayerVisible = false;
size_t count = layers.size();
for (size_t i=0 ; i<count ; i++) {
- if (layers[i]->isSecure()) {
+ const sp<LayerBase>& layer(layers[i]);
+ if (layer->isSecure()) {
mSecureLayerVisible = true;
}
}
@@ -365,74 +366,72 @@ status_t DisplayDevice::orientationToTransfrom(
}
void DisplayDevice::setProjection(int orientation,
- const Rect& viewport, const Rect& frame) {
- mOrientation = orientation;
- mViewport = viewport;
- mFrame = frame;
- updateGeometryTransform();
-}
+ const Rect& newViewport, const Rect& newFrame) {
+ Rect viewport(newViewport);
+ Rect frame(newFrame);
-void DisplayDevice::updateGeometryTransform() {
- int w = mDisplayWidth;
- int h = mDisplayHeight;
- Transform TL, TP, R, S;
- if (DisplayDevice::orientationToTransfrom(
- mOrientation, w, h, &R) == NO_ERROR) {
- dirtyRegion.set(bounds());
-
- Rect viewport(mViewport);
- Rect frame(mFrame);
-
- if (!frame.isValid()) {
- // the destination frame can be invalid if it has never been set,
- // in that case we assume the whole display frame.
- frame = Rect(w, h);
- }
+ const int w = mDisplayWidth;
+ const int h = mDisplayHeight;
- if (viewport.isEmpty()) {
- // viewport can be invalid if it has never been set, in that case
- // we assume the whole display size.
- // it's also invalid to have an empty viewport, so we handle that
- // case in the same way.
- viewport = Rect(w, h);
- if (R.getOrientation() & Transform::ROT_90) {
- // viewport is always specified in the logical orientation
- // of the display (ie: post-rotation).
- swap(viewport.right, viewport.bottom);
- }
- }
+ Transform R;
+ DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
- float src_width = viewport.width();
- float src_height = viewport.height();
- float dst_width = frame.width();
- float dst_height = frame.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);
- }
+ if (!frame.isValid()) {
+ // the destination frame can be invalid if it has never been set,
+ // in that case we assume the whole display frame.
+ frame = Rect(w, h);
+ }
- float src_x = viewport.left;
- float src_y = viewport.top;
- float dst_x = frame.left;
- float dst_y = frame.top;
- TL.set(-src_x, -src_y);
- TP.set(dst_x, dst_y);
-
- // The viewport and frame are both in the logical orientation.
- // Apply the logical translation, scale to physical size, apply the
- // physical translation and finally rotate to the physical orientation.
- mGlobalTransform = R * TP * S * TL;
-
- const uint8_t type = mGlobalTransform.getType();
- mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
- (type >= Transform::SCALE));
-
- mScissor = mGlobalTransform.transform(mViewport);
- if (mScissor.isEmpty()) {
- mScissor.set(getBounds());
+ if (viewport.isEmpty()) {
+ // viewport can be invalid if it has never been set, in that case
+ // we assume the whole display size.
+ // it's also invalid to have an empty viewport, so we handle that
+ // case in the same way.
+ viewport = Rect(w, h);
+ if (R.getOrientation() & Transform::ROT_90) {
+ // viewport is always specified in the logical orientation
+ // of the display (ie: post-rotation).
+ swap(viewport.right, viewport.bottom);
}
}
+
+ dirtyRegion.set(getBounds());
+
+ Transform TL, TP, S;
+ float src_width = viewport.width();
+ float src_height = viewport.height();
+ float dst_width = frame.width();
+ float dst_height = frame.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;
+ TL.set(-src_x, -src_y);
+ TP.set(dst_x, dst_y);
+
+ // The viewport and frame are both in the logical orientation.
+ // Apply the logical translation, scale to physical size, apply the
+ // physical translation and finally rotate to the physical orientation.
+ mGlobalTransform = R * TP * S * TL;
+
+ const uint8_t type = mGlobalTransform.getType();
+ mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
+ (type >= Transform::SCALE));
+
+ mScissor = mGlobalTransform.transform(viewport);
+ if (mScissor.isEmpty()) {
+ mScissor.set(getBounds());
+ }
+
+ mOrientation = orientation;
+ mViewport = viewport;
+ mFrame = frame;
}
void DisplayDevice::dump(String8& result, char* buffer, size_t SIZE) const {
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index bb6eb70e91..c7534af61c 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -105,8 +105,8 @@ public:
int getOrientation() const { return mOrientation; }
const Transform& getTransform() const { return mGlobalTransform; }
- const Rect& getViewport() const { return mViewport; }
- const Rect& getFrame() const { return mFrame; }
+ const Rect getViewport() const { return mViewport; }
+ const Rect getFrame() const { return mFrame; }
const Rect& getScissor() const { return mScissor; }
bool needsFiltering() const { return mNeedsFiltering; }
@@ -197,8 +197,6 @@ private:
static status_t orientationToTransfrom(int orientation,
int w, int h, Transform* tr);
- void updateGeometryTransform();
-
uint32_t mLayerStack;
int mOrientation;
// user-provided visible area of the layer stack
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 24b122ab8a..ba56c23102 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -306,8 +306,11 @@ void LayerBase::setPerFrameData(const sp<const DisplayDevice>& hw,
// we have to set the visible region on every frame because
// we currently free it during onLayerDisplayed(), which is called
// after HWComposer::commit() -- every frame.
+ // Apply this display's projection's viewport to the visible region
+ // before giving it to the HWC HAL.
const Transform& tr = hw->getTransform();
- layer.setVisibleRegionScreen(tr.transform(visibleRegion));
+ Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
+ layer.setVisibleRegionScreen(visible);
}
void LayerBase::setAcquireFence(const sp<const DisplayDevice>& hw,