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
This commit is contained in:
parent
f5f714aa18
commit
a8bca8d84b
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue