diff options
Diffstat (limited to 'services')
-rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 19 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 46 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlingerConsumer.cpp | 13 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlingerConsumer.h | 10 |
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; }; // ---------------------------------------------------------------------------- |