summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp19
-rw-r--r--services/surfaceflinger/DisplayDevice.h1
-rw-r--r--services/surfaceflinger/Layer.cpp46
-rw-r--r--services/surfaceflinger/SurfaceFlingerConsumer.cpp13
-rw-r--r--services/surfaceflinger/SurfaceFlingerConsumer.h10
5 files changed, 87 insertions, 2 deletions
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 917d4cd..800137b 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -344,6 +344,25 @@ void DisplayDevice::setLayerStack(uint32_t stack) {
// ----------------------------------------------------------------------------
+uint32_t DisplayDevice::getOrientationTransform() const {
+ uint32_t transform = 0;
+ switch (mOrientation) {
+ case DisplayState::eOrientationDefault:
+ transform = Transform::ROT_0;
+ break;
+ case DisplayState::eOrientation90:
+ transform = Transform::ROT_90;
+ break;
+ case DisplayState::eOrientation180:
+ transform = Transform::ROT_180;
+ break;
+ case DisplayState::eOrientation270:
+ transform = Transform::ROT_270;
+ break;
+ }
+ return transform;
+}
+
status_t DisplayDevice::orientationToTransfrom(
int orientation, int w, int h, Transform* tr)
{
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index e0b1370..c3abe89 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -111,6 +111,7 @@ public:
void setProjection(int orientation, const Rect& viewport, const Rect& frame);
int getOrientation() const { return mOrientation; }
+ uint32_t getOrientationTransform() const;
const Transform& getTransform() const { return mGlobalTransform; }
const Rect getViewport() const { return mViewport; }
const Rect getFrame() const { return mFrame; }
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index b610c20..61af51f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -376,7 +376,21 @@ void Layer::setGeometry(
*/
const Transform bufferOrientation(mCurrentTransform);
- const Transform transform(tr * s.transform * bufferOrientation);
+ Transform transform(tr * s.transform * bufferOrientation);
+
+ if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
+ /*
+ * the code below applies the display's inverse transform to the buffer
+ */
+ uint32_t invTransform = hw->getOrientationTransform();
+ // calculate the inverse transform
+ if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+ invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
+ NATIVE_WINDOW_TRANSFORM_FLIP_H;
+ }
+ // and apply to the current transform
+ transform = transform * Transform(invTransform);
+ }
// this gives us only the "orientation" component of the transform
const uint32_t orientation = transform.getOrientation();
@@ -489,6 +503,34 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
+ if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
+
+ /*
+ * the code below applies the display's inverse transform to the texture transform
+ */
+
+ // create a 4x4 transform matrix from the display transform flags
+ const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
+ const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
+ const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
+
+ mat4 tr;
+ uint32_t transform = hw->getOrientationTransform();
+ if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
+ tr = tr * rot90;
+ if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
+ tr = tr * flipH;
+ if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
+ tr = tr * flipV;
+
+ // calculate the inverse
+ tr = inverse(tr);
+
+ // and finally apply it to the original texture matrix
+ const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
+ memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
+ }
+
// Set things up for texturing.
mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
mTexture.setFiltering(useFiltering);
@@ -533,7 +575,7 @@ void Layer::drawWithOpenGL(
*
* The GL code below is more logical (imho), and the difference with
* HWC is due to a limitation of the HWC API to integers -- a question
- * is suspend is wether we should ignore this problem or revert to
+ * is suspend is whether we should ignore this problem or revert to
* GL composition when a buffer scaling is applied (maybe with some
* minimal value)? Or, we could make GL behave like HWC -- but this feel
* like more of a hack.
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index 552372b..6dc093e 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -99,6 +99,19 @@ status_t SurfaceFlingerConsumer::bindTextureImage()
return bindTextureImageLocked();
}
+status_t SurfaceFlingerConsumer::acquireBufferLocked(
+ BufferQueue::BufferItem *item, nsecs_t presentWhen) {
+ status_t result = GLConsumer::acquireBufferLocked(item, presentWhen);
+ if (result == NO_ERROR) {
+ mTransformToDisplayInverse = item->mTransformToDisplayInverse;
+ }
+ return result;
+}
+
+bool SurfaceFlingerConsumer::getTransformToDisplayInverse() const {
+ return mTransformToDisplayInverse;
+}
+
// We need to determine the time when a buffer acquired now will be
// displayed. This can be calculated:
// time when previous buffer's actual-present fence was signaled
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index c7fc164..688ad32 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -40,6 +40,8 @@ public:
virtual ~BufferRejecter() { }
};
+ virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item, nsecs_t presentWhen);
+
// This version of updateTexImage() takes a functor that may be used to
// reject the newly acquired buffer. Unlike the GLConsumer version,
// this does not guarantee that the buffer has been bound to the GL
@@ -49,8 +51,16 @@ public:
// See GLConsumer::bindTextureImageLocked().
status_t bindTextureImage();
+ // must be called from SF main thread
+ bool getTransformToDisplayInverse() const;
+
private:
nsecs_t computeExpectedPresent();
+
+ // Indicates this buffer must be transformed by the inverse transform of the screen
+ // it is displayed onto. This is applied after GLConsumer::mCurrentTransform.
+ // This must be set/read from SurfaceFlinger's main thread.
+ bool mTransformToDisplayInverse;
};
// ----------------------------------------------------------------------------