summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/Layer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/Layer.cpp')
-rw-r--r--services/surfaceflinger/Layer.cpp129
1 files changed, 110 insertions, 19 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5ff79a9..c346a2f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -84,7 +84,8 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
mQueueItemCondition(),
mQueueItems(),
mLastFrameNumberReceived(0),
- mUpdateTexImageFailed(false)
+ mUpdateTexImageFailed(false),
+ mTransformHint(0)
{
mCurrentCrop.makeInvalid();
mFlinger->getRenderEngine().genTextures(1, &mTextureName);
@@ -103,11 +104,15 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
mName = name;
+ mCurrentState.active.x = 0;
+ mCurrentState.active.y = 0;
mCurrentState.active.w = w;
mCurrentState.active.h = h;
mCurrentState.active.crop.makeInvalid();
+ mCurrentState.active.isPositionPending = false;
mCurrentState.z = 0;
mCurrentState.alpha = 0xFF;
+ mCurrentState.blur = 0xFF;
mCurrentState.layerStack = 0;
mCurrentState.flags = layerFlags;
mCurrentState.sequence = 0;
@@ -320,11 +325,13 @@ Rect Layer::getContentCrop() const {
return crop;
}
-static Rect reduce(const Rect& win, const Region& exclude) {
+Rect Layer::reduce(const Rect& win, const Region& exclude) const{
if (CC_LIKELY(exclude.isEmpty())) {
return win;
}
- if (exclude.isRect()) {
+ Rect tmp;
+ win.intersect(exclude.getBounds(), &tmp);
+ if (exclude.isRect() && !tmp.isEmpty()) {
return win.reduce(exclude.getBounds());
}
return Region(win).subtract(exclude).getBounds();
@@ -494,6 +501,7 @@ void Layer::setGeometry(
frame.intersect(hw->getViewport(), &frame);
const Transform& tr(hw->getTransform());
layer.setFrame(tr.transform(frame));
+ setPosition(hw, layer, s);
layer.setCrop(computeCrop(hw));
layer.setPlaneAlpha(s.alpha);
@@ -578,6 +586,7 @@ void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
}
}
}
+ setAcquiredFenceIfBlit(fenceFd, layer);
layer.setAcquireFenceFd(fenceFd);
}
@@ -605,21 +614,21 @@ Rect Layer::getPosition(
// drawing...
// ---------------------------------------------------------------------------
-void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
+void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) {
onDraw(hw, clip, false);
}
void Layer::draw(const sp<const DisplayDevice>& hw,
- bool useIdentityTransform) const {
+ bool useIdentityTransform) {
onDraw(hw, Region(hw->bounds()), useIdentityTransform);
}
-void Layer::draw(const sp<const DisplayDevice>& hw) const {
+void Layer::draw(const sp<const DisplayDevice>& hw) {
onDraw(hw, Region(hw->bounds()), false);
}
void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
- bool useIdentityTransform) const
+ bool useIdentityTransform)
{
ATRACE_CALL();
@@ -663,8 +672,8 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
RenderEngine& engine(mFlinger->getRenderEngine());
-
- if (!blackOutLayer) {
+ if (!blackOutLayer ||
+ ((hw->getDisplayType() == HWC_DISPLAY_PRIMARY) && canAllowGPUForProtected())) {
// TODO: we could be more subtle with isFixedSize()
const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
@@ -750,8 +759,19 @@ void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
* minimal value)? Or, we could make GL behave like HWC -- but this feel
* like more of a hack.
*/
- const Rect win(computeBounds());
-
+ Rect win(s.active.w, s.active.h);
+ if(!s.active.crop.isEmpty()) {
+ win = s.active.crop;
+ }
+#ifdef QTI_BSP
+ win = s.transform.transform(win);
+ win.intersect(hw->getViewport(), &win);
+ win = s.transform.inverse().transform(win);
+ win.intersect(Rect(s.active.w, s.active.h), &win);
+ win = reduce(win, s.activeTransparentRegion);
+#else
+ win = reduce(win, s.activeTransparentRegion);
+#endif
float left = float(win.left) / float(s.active.w);
float top = float(win.top) / float(s.active.h);
float right = float(win.right) / float(s.active.w);
@@ -818,16 +838,49 @@ void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
bool useIdentityTransform) const
{
const Layer::State& s(getDrawingState());
- const Transform tr(useIdentityTransform ?
+ Transform tr(useIdentityTransform ?
hw->getTransform() : hw->getTransform() * s.transform);
const uint32_t hw_h = hw->getHeight();
Rect win(s.active.w, s.active.h);
if (!s.active.crop.isEmpty()) {
win.intersect(s.active.crop, &win);
}
- // subtract the transparent region and snap to the bounds
+#ifdef QTI_BSP
+ win = s.transform.transform(win);
+ win.intersect(hw->getViewport(), &win);
+ win = s.transform.inverse().transform(win);
+ win.intersect(Rect(s.active.w, s.active.h), &win);
win = reduce(win, s.activeTransparentRegion);
-
+ const Transform bufferOrientation(mCurrentTransform);
+ Transform transform(tr * s.transform * bufferOrientation);
+ if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
+ uint32_t invTransform = hw->getOrientationTransform();
+ uint32_t t_orientation = transform.getOrientation();
+ if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+ invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
+ NATIVE_WINDOW_TRANSFORM_FLIP_H;
+ bool is_h_flipped = (t_orientation &
+ NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
+ bool is_v_flipped = (t_orientation &
+ NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
+ if (is_h_flipped != is_v_flipped) {
+ t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
+ NATIVE_WINDOW_TRANSFORM_FLIP_H;
+ }
+ transform = Transform(t_orientation) * Transform(invTransform);
+ }
+ }
+ const uint32_t orientation = transform.getOrientation();
+ if (!(mTransformHint | mCurrentTransform | orientation)) {
+ tr = hw->getTransform();
+ if (!useIdentityTransform) {
+ win = s.transform.transform(win);
+ win.intersect(hw->getViewport(), &win);
+ }
+ }
+#else
+ win = reduce(win, s.activeTransparentRegion);
+#endif
Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
position[0] = tr.transform(win.left, win.top);
position[1] = tr.transform(win.left, win.bottom);
@@ -977,6 +1030,17 @@ uint32_t Layer::doTransaction(uint32_t flags) {
if (flags & eDontUpdateGeometryState) {
} else {
Layer::State& editCurrentState(getCurrentState());
+ // If a position change was requested, and we have the correct
+ // buffer size, no need to delay, update state now.
+ if (editCurrentState.requested.isPositionPending) {
+ float requestedX = editCurrentState.requested.x;
+ float requestedY = editCurrentState.requested.y;
+ if (requestedX != editCurrentState.active.x ||
+ requestedY != editCurrentState.active.y) {
+ editCurrentState.requested.isPositionPending = false;
+ editCurrentState.transform.set(requestedX, requestedY);
+ }
+ }
editCurrentState.active = c.requested;
}
@@ -1014,10 +1078,15 @@ uint32_t Layer::setTransactionFlags(uint32_t flags) {
}
bool Layer::setPosition(float x, float y) {
- if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
+ if ((mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y
+ && !mCurrentState.requested.isPositionPending) ||
+ (mCurrentState.requested.isPositionPending && mCurrentState.requested.x == x
+ && mCurrentState.requested.y == y))
return false;
mCurrentState.sequence++;
- mCurrentState.transform.set(x, y);
+ mCurrentState.requested.x = x;
+ mCurrentState.requested.y = y;
+ mCurrentState.requested.isPositionPending = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -1029,6 +1098,14 @@ bool Layer::setLayer(uint32_t z) {
setTransactionFlags(eTransactionNeeded);
return true;
}
+bool Layer::setBlur(uint8_t blur) {
+ if (mCurrentState.blur == blur)
+ return false;
+ mCurrentState.sequence++;
+ mCurrentState.blur = blur;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
bool Layer::setSize(uint32_t w, uint32_t h) {
if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
return false;
@@ -1232,6 +1309,19 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
(bufWidth == front.requested.w &&
bufHeight == front.requested.h))
{
+
+ // If a position change was requested along with a resize.
+ // Now that we have the correct buffer size, update the position as well.
+ if (current.requested.isPositionPending) {
+ float requestedX = current.requested.x;
+ float requestedY = current.requested.y;
+ if (requestedX != current.active.x || requestedY != current.active.y) {
+ front.transform.set(requestedX, requestedY);
+ current.transform.set(requestedX, requestedY);
+ current.requested.isPositionPending = false;
+ }
+ }
+
// Here we pretend the transaction happened by updating the
// current and drawing states. Drawing state is only accessed
// in this thread, no need to have it locked
@@ -1440,7 +1530,7 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const
return usage;
}
-void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
+void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) {
uint32_t orientation = 0;
if (!mFlinger->mDebugDisableTransformHint) {
// The transform hint is used to improve performance, but we can
@@ -1453,6 +1543,7 @@ void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
}
}
mSurfaceFlingerConsumer->setTransformHint(orientation);
+ mTransformHint = orientation;
}
// ----------------------------------------------------------------------------
@@ -1477,13 +1568,13 @@ void Layer::dump(String8& result, Colorizer& colorizer) const
result.appendFormat( " "
"layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
"isOpaque=%1d, invalidate=%1d, "
- "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
+ "alpha=0x%02x, blur=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
" client=%p\n",
s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
s.active.crop.left, s.active.crop.top,
s.active.crop.right, s.active.crop.bottom,
isOpaque(s), contentDirty,
- s.alpha, s.flags,
+ s.alpha, s.blur, s.flags,
s.transform[0][0], s.transform[0][1],
s.transform[1][0], s.transform[1][1],
client.get());