diff options
author | 2013-02-27 22:03:19 -0800 | |
---|---|---|
committer | 2013-02-28 18:43:04 -0800 | |
commit | a8bca8d84b559e7dcca010f7d6514333004020c7 (patch) | |
tree | 27a973a8e286596c67879fac333648427585cee1 | |
parent | f5f714aa188884098aaecbe39d0bc61b40311c0d (diff) |
refactor the crop region for hwc is calculated/set
- the crop region is now always calculated and set
in LayerBase::setGeometry which uses new virtuals to
access the "content" crop and transform (which are
provided by the Layer subclass)
Change-Id: Ib7769bdec0917dd248f926600c14ddf9ea84897a
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 47 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 4 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBase.cpp | 66 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBase.h | 15 |
4 files changed, 90 insertions, 42 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 439acb52ae..c9f1eb51d8 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -19,7 +19,6 @@ #include <stdlib.h> #include <stdint.h> #include <sys/types.h> -#include <math.h> #include <cutils/compiler.h> #include <cutils/native_handle.h> @@ -200,48 +199,27 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, return NO_ERROR; } -Rect Layer::computeBufferCrop() const { - // Start with the SurfaceFlingerConsumer's buffer crop... +Rect Layer::getContentCrop() const { + // this is the crop rectangle that applies to the buffer + // itself (as opposed to the window) Rect crop; if (!mCurrentCrop.isEmpty()) { + // if the buffer crop is defined, we use that crop = mCurrentCrop; - } else if (mActiveBuffer != NULL){ - crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); + } else if (mActiveBuffer != NULL) { + // otherwise we use the whole buffer + crop = mActiveBuffer->getBounds(); } else { + // if we don't have a buffer yet, we use an empty/invalid crop crop.makeInvalid(); - return crop; } - - // ... then reduce that in the same proportions as the window crop reduces - // the window size. - const State& s(drawingState()); - if (!s.active.crop.isEmpty()) { - // Transform the window crop to match the buffer coordinate system, - // which means using the inverse of the current transform set on the - // SurfaceFlingerConsumer. - uint32_t invTransform = mCurrentTransform; - int winWidth = s.active.w; - int winHeight = s.active.h; - if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { - invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | - NATIVE_WINDOW_TRANSFORM_FLIP_H; - winWidth = s.active.h; - winHeight = s.active.w; - } - Rect winCrop = s.active.crop.transform(invTransform, - s.active.w, s.active.h); - - float xScale = float(crop.width()) / float(winWidth); - float yScale = float(crop.height()) / float(winHeight); - crop.left += int(ceilf(float(winCrop.left) * xScale)); - crop.top += int(ceilf(float(winCrop.top) * yScale)); - crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale)); - crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale)); - } - return crop; } +uint32_t Layer::getContentTransform() const { + return mCurrentTransform; +} + void Layer::setGeometry( const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer) @@ -278,7 +256,6 @@ void Layer::setGeometry( } else { layer.setTransform(finalTransform); } - layer.setCrop(computeBufferCrop()); } void Layer::setPerFrameData(const sp<const DisplayDevice>& hw, diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index a82767b755..242493df9b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -103,6 +103,9 @@ public: // the current orientation of the display device. virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const; + virtual Rect getContentCrop() const; + virtual uint32_t getContentTransform() const; + protected: virtual void onFirstRef(); virtual void dump(String8& result, char* scratch, size_t size) const; @@ -115,7 +118,6 @@ private: uint32_t getEffectiveUsage(uint32_t usage) const; bool isCropped() const; - Rect computeBufferCrop() const; static bool getOpacityForFormat(uint32_t format); // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp index ba56c23102..572e7c8913 100644 --- a/services/surfaceflinger/LayerBase.cpp +++ b/services/surfaceflinger/LayerBase.cpp @@ -17,6 +17,7 @@ #include <stdlib.h> #include <stdint.h> #include <sys/types.h> +#include <math.h> #include <utils/Errors.h> #include <utils/Log.h> @@ -267,6 +268,61 @@ Region LayerBase::latchBuffer(bool& recomputeVisibleRegions) { return result; } + +Rect LayerBase::getContentCrop() const { + // regular layers just use their active area as the content crop + const State& s(drawingState()); + return Rect(s.active.w, s.active.h); +} + +uint32_t LayerBase::getContentTransform() const { + // regular layers don't have a content transform + return 0; +} + +Rect LayerBase::computeCrop(const sp<const DisplayDevice>& hw) const { + // the content crop is the area of the content that gets scaled to the + // layer's size. + Rect crop(getContentCrop()); + + // the active.crop is the area of the window that gets cropped, but not + // scaled in any ways. + const State& s(drawingState()); + Rect activeCrop(s.active.crop); + if (!activeCrop.isEmpty()) { + // Transform the window crop to match the buffer coordinate system, + // which means using the inverse of the current transform set on the + // SurfaceFlingerConsumer. + uint32_t invTransform = getContentTransform(); + int winWidth = s.active.w; + int winHeight = s.active.h; + if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { + invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | + NATIVE_WINDOW_TRANSFORM_FLIP_H; + winWidth = s.active.h; + winHeight = s.active.w; + } + const Rect winCrop = activeCrop.transform( + invTransform, s.active.w, s.active.h); + + // the code below essentially performs a scaled intersection + // of crop and winCrop + float xScale = float(crop.width()) / float(winWidth); + float yScale = float(crop.height()) / float(winHeight); + + int insetL = int(ceilf( winCrop.left * xScale)); + int insetT = int(ceilf( winCrop.top * yScale)); + int insetR = int(ceilf((winWidth - winCrop.right ) * xScale)); + int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale)); + + crop.left += insetL; + crop.top += insetT; + crop.right -= insetR; + crop.bottom -= insetB; + } + return crop; +} + void LayerBase::setGeometry( const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer) @@ -290,15 +346,13 @@ void LayerBase::setGeometry( } - Rect bounds(computeBounds()); - // apply the layer's transform, followed by the display's global transform // here we're guaranteed that the layer's transform preserves rects - const Transform& tr = hw->getTransform(); - Rect frame(tr.transform(s.transform.transform(bounds))); - layer.setFrame(frame); - layer.setCrop(bounds); + Rect frame(s.transform.transform(computeBounds())); + const Transform& tr(hw->getTransform()); + layer.setFrame(tr.transform(frame)); + layer.setCrop(computeCrop(hw)); } void LayerBase::setPerFrameData(const sp<const DisplayDevice>& hw, diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index c2624df5d9..ecae2d99ce 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -260,6 +260,18 @@ public: */ virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const { } + /** + * returns the rectangle that crops the content of the layer and scales it + * to the layer's size. + */ + virtual Rect getContentCrop() const; + + /* + * returns the transform bits (90 rotation / h-flip / v-flip) of the + * layer's content + */ + virtual uint32_t getContentTransform() const; + /** always call base class first */ virtual void dump(String8& result, char* scratch, size_t size) const; virtual void shortDump(String8& result, char* scratch, size_t size) const; @@ -282,6 +294,9 @@ public: void setFiltering(bool filtering); bool getFiltering() const; +private: + Rect computeCrop(const sp<const DisplayDevice>& hw) const; + protected: void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip, GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const; |