Bug 832383 - Add support for complex visible regions to HwcComposer2D. r=mwu

This commit is contained in:
Diego Wilson 2013-04-29 17:21:54 -07:00
parent 20e6b017de
commit f4373c738c
2 changed files with 75 additions and 8 deletions

View File

@ -193,6 +193,52 @@ PrepareLayerRects(nsIntRect aVisible, const gfxMatrix& aTransform,
return true;
}
/**
* Prepares hwc layer visible region required for hwc composition
*
* @param aVisible Input. Layer's unclipped visible region
* The origin is the top-left corner of the layer
* @param aTransform Input. Layer's transformation matrix
* It transforms from layer space to screen space
* @param aClip Input. A clipping rectangle.
* The origin is the top-left corner of the screen
* @param aBufferRect Input. The layer's buffer bounds
* The origin is the top-left corner of the layer
* @param aVisibleRegionScreen Output. Visible region in screen space.
* The origin is the top-left corner of the screen
* @return true if the layer should be rendered.
* false if the layer can be skipped
*/
static bool
PrepareVisibleRegion(const nsIntRegion& aVisible,
const gfxMatrix& aTransform,
nsIntRect aClip, nsIntRect aBufferRect,
RectVector* aVisibleRegionScreen) {
nsIntRegionRectIterator rect(aVisible);
bool isVisible = false;
while (const nsIntRect* visibleRect = rect.Next()) {
hwc_rect_t visibleRectScreen;
gfxRect screenRect;
screenRect.IntersectRect(gfxRect(*visibleRect), aBufferRect);
screenRect = aTransform.TransformBounds(screenRect);
screenRect.IntersectRect(screenRect, aClip);
screenRect.RoundIn();
if (screenRect.IsEmpty()) {
continue;
}
visibleRectScreen.left = screenRect.x;
visibleRectScreen.top = screenRect.y;
visibleRectScreen.right = screenRect.XMost();
visibleRectScreen.bottom = screenRect.YMost();
aVisibleRegionScreen->push_back(visibleRectScreen);
isVisible = true;
}
return isVisible;
}
/**
* Calculates the layer's clipping rectangle
*
@ -260,12 +306,6 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
return false;
}
if (visibleRegion.GetNumRects() > 1) {
// FIXME/bug 808339
LOGD("Layer has nontrivial visible region");
return false;
}
nsIntRect clip;
if (!CalculateClipRect(aParentTransform * aGLWorldTransform,
aLayer->GetEffectiveClipRect(),
@ -385,8 +425,22 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
hwcLayer.transform |= state.YFlipped() ? HWC_TRANSFORM_FLIP_V : 0;
hwc_region_t region;
region.numRects = 1;
region.rects = &(hwcLayer.displayFrame);
if (visibleRegion.GetNumRects() > 1) {
mVisibleRegions.push_back(RectVector());
RectVector* visibleRects = &(mVisibleRegions.back());
if(!PrepareVisibleRegion(visibleRegion,
transform * aGLWorldTransform,
clip,
bufferRect,
visibleRects)) {
return true;
}
region.numRects = visibleRects->size();
region.rects = &((*visibleRects)[0]);
} else {
region.numRects = 1;
region.rects = &(hwcLayer.displayFrame);
}
hwcLayer.visibleRegionScreen = region;
} else {
hwcLayer.flags |= HWC_COLOR_FILL;
@ -412,6 +466,10 @@ HwcComposer2D::TryRender(Layer* aRoot,
mList->numHwLayers = 0;
}
// XXX: The clear() below means all rect vectors will be have to be
// reallocated. We may want to avoid this if possible
mVisibleRegions.clear();
if (!PrepareLayerList(aRoot,
mScreenRect,
gfxMatrix(),

View File

@ -20,6 +20,8 @@
#include "Composer2D.h"
#include "HWComposer.h"
#include "Layers.h"
#include <vector>
#include <list>
namespace mozilla {
@ -28,6 +30,10 @@ class ContainerLayer;
class Layer;
}
//Holds a dynamically allocated vector of rectangles
//used to decribe the complex visible region of a layer
typedef std::vector<hwc_rect_t> RectVector;
class HwcComposer2D : public android::HWComposer,
public mozilla::layers::Composer2D {
public:
@ -54,6 +60,9 @@ private:
nsIntRect mScreenRect;
int mMaxLayerCount;
bool mColorFill;
//Holds all the dynamically allocated RectVectors needed
//to render the current frame
std::list<RectVector> mVisibleRegions;
};
} // namespace mozilla