Bug 738413 - Part 2: Use OpaqueRect API in BasicLayers with non-cairo contexts. r=roc

This commit is contained in:
Bas Schouten 2012-05-03 23:31:02 +02:00
parent 6d00e6392f
commit b058c7e333
3 changed files with 58 additions and 12 deletions

View File

@ -74,6 +74,8 @@
#define PIXMAN_DONT_DEFINE_STDINT
#include "pixman.h"
using namespace mozilla::gfx;
namespace mozilla {
namespace layers {
@ -1946,8 +1948,10 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
bool pushedTargetOpaqueRect = false;
nsRefPtr<gfxASurface> currentSurface = aTarget->CurrentSurface();
DrawTarget *dt = aTarget->GetDrawTarget();
const nsIntRect& bounds = visibleRegion.GetBounds();
if (is2D) {
if (aTarget->IsCairo()) {
const gfxRect& targetOpaqueRect = currentSurface->GetOpaqueRect();
@ -1960,6 +1964,25 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
aTarget->UserToDevice(gfxRect(bounds.x, bounds.y, bounds.width, bounds.height)));
pushedTargetOpaqueRect = true;
}
} else {
const IntRect& targetOpaqueRect = dt->GetOpaqueRect();
// Try to annotate currentSurface with a region of pixels that have been
// (or will be) painted opaque, if no such region is currently set.
if (targetOpaqueRect.IsEmpty() && visibleRegion.GetNumRects() == 1 &&
(aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
!transform.HasNonAxisAlignedTransform()) {
Rect opaqueRect = dt->GetTransform().TransformBounds(
Rect(bounds.x, bounds.y, bounds.width, bounds.height));
opaqueRect.RoundIn();
IntRect intOpaqueRect;
if (gfxUtils::RectToIntRect(opaqueRect, &intOpaqueRect)) {
aTarget->GetDrawTarget()->SetOpaqueRect(intOpaqueRect);
pushedTargetOpaqueRect = true;
}
}
}
}
nsRefPtr<gfxContext> groupTarget;
@ -1970,7 +1993,11 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
gfxASurface::CONTENT_COLOR_ALPHA);
if (!untransformedSurface) {
if (pushedTargetOpaqueRect) {
if (aTarget->IsCairo()) {
currentSurface->SetOpaqueRect(gfxRect(0, 0, 0, 0));
} else {
dt->SetOpaqueRect(IntRect());
}
}
NS_ASSERTION(needsSaveRestore, "Should always need to restore with 3d transforms!");
aTarget->Restore();
@ -2085,7 +2112,11 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
}
if (pushedTargetOpaqueRect) {
if (aTarget->IsCairo()) {
currentSurface->SetOpaqueRect(gfxRect(0, 0, 0, 0));
} else {
dt->SetOpaqueRect(IntRect());
}
}
if (needsSaveRestore) {

View File

@ -574,6 +574,14 @@ gfxUtils::GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut)
return gfxRect(aOut->x, aOut->y, aOut->width, aOut->height).IsEqualEdges(aIn);
}
bool
gfxUtils::RectToIntRect(const Rect& aIn, IntRect* aOut)
{
*aOut = IntRect(int32_t(aIn.X()), int32_t(aIn.Y()),
int32_t(aIn.Width()), int32_t(aIn.Height()));
return Rect(aOut->x, aOut->y, aOut->width, aOut->height).IsEqualEdges(aIn);
}
void
gfxUtils::GetYCbCrToRGBDestFormatAndSize(const PlanarYCbCrImage::Data& aData,
gfxASurface::gfxImageFormat& aSuggestedFormat,

View File

@ -125,6 +125,13 @@ public:
*/
static bool GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut);
/**
* If aIn can be represented exactly using an nsIntRect (i.e.
* integer-aligned edges and coordinates in the PRInt32 range) then we
* set aOut to that rectangle, otherwise return failure.
*/
static bool RectToIntRect(const mozilla::gfx::Rect& aIn, mozilla::gfx::IntRect* aOut);
/**
* Return the smallest power of kScaleResolution (2) greater than or equal to
* aVal.