Bug 1386965 - Support async painting component-alpha layers. r=dvander
--- a/gfx/layers/RotatedBuffer.cpp
+++ b/gfx/layers/RotatedBuffer.cpp
@@ -309,16 +309,17 @@ RotatedContentBuffer::BorrowDrawTargetFo
-quadrantRect.y);
if (aSetTransform) {
mLoanedDrawTarget->SetTransform(transform);
} else {
MOZ_ASSERT(aOutMatrix);
*aOutMatrix = transform;
}
+
return mLoanedDrawTarget;
}
void
BorrowDrawTarget::ReturnDrawTarget(gfx::DrawTarget*& aReturned)
{
MOZ_ASSERT(mLoanedDrawTarget);
MOZ_ASSERT(aReturned == mLoanedDrawTarget);
@@ -746,36 +747,39 @@ RotatedContentBuffer::BorrowDrawTargetFo
{
if (aPaintState.mMode == SurfaceMode::SURFACE_NONE) {
return nullptr;
}
Matrix transform;
DrawTarget* result = BorrowDrawTargetForQuadrantUpdate(aPaintState.mRegionToDraw.GetBounds(),
BUFFER_BOTH, aIter,
- false, &transform);
+ false,
+ &transform);
if (!result) {
return nullptr;
}
- ExpandDrawRegion(aPaintState, aIter, result->GetBackendType());
+ nsIntRegion regionToDraw =
+ ExpandDrawRegion(aPaintState, aIter, result->GetBackendType());
RefPtr<CapturedPaintState> state =
- new CapturedPaintState(aPaintState.mRegionToDraw,
+ new CapturedPaintState(regionToDraw,
result,
- nullptr, /* aTargetOnWhite */
+ mDTBufferOnWhite,
transform,
aPaintState.mMode,
aPaintState.mContentType);
return state;
}
/*static */ bool
RotatedContentBuffer::PrepareDrawTargetForPainting(CapturedPaintState* aState)
{
+ MOZ_ASSERT(aState);
RefPtr<DrawTarget> target = aState->mTarget;
RefPtr<DrawTarget> whiteTarget = aState->mTargetOnWhite;
if (aState->mSurfaceMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
if (!target || !target->IsValid() ||
!whiteTarget || !whiteTarget->IsValid()) {
// This can happen in release builds if allocating one of the two buffers
// failed. This in turn can happen if unreasonably large textures are
@@ -796,17 +800,17 @@ RotatedContentBuffer::PrepareDrawTargetF
const IntRect& rect = iter.Get();
target->ClearRect(Rect(rect.x, rect.y, rect.width, rect.height));
}
}
return true;
}
-void
+nsIntRegion
RotatedContentBuffer::ExpandDrawRegion(PaintState& aPaintState,
DrawIterator* aIter,
BackendType aBackendType)
{
nsIntRegion* drawPtr = &aPaintState.mRegionToDraw;
if (aIter) {
// The iterators draw region currently only contains the bounds of the region,
// this makes it the precise region.
@@ -814,51 +818,39 @@ RotatedContentBuffer::ExpandDrawRegion(P
drawPtr = &aIter->mDrawRegion;
}
if (aBackendType == BackendType::DIRECT2D ||
aBackendType == BackendType::DIRECT2D1_1) {
// Simplify the draw region to avoid hitting expensive drawing paths
// for complex regions.
drawPtr->SimplifyOutwardByArea(100 * 100);
}
+ return *drawPtr;
}
DrawTarget*
RotatedContentBuffer::BorrowDrawTargetForPainting(PaintState& aPaintState,
DrawIterator* aIter /* = nullptr */)
{
- if (aPaintState.mMode == SurfaceMode::SURFACE_NONE) {
- return nullptr;
- }
+ RefPtr<CapturedPaintState> capturedState =
+ BorrowDrawTargetForRecording(aPaintState, aIter);
- DrawTarget* result = BorrowDrawTargetForQuadrantUpdate(aPaintState.mRegionToDraw.GetBounds(),
- BUFFER_BOTH, aIter);
- if (!result) {
+ if (!capturedState) {
return nullptr;
}
- ExpandDrawRegion(aPaintState, aIter, result->GetBackendType());
-
- nsIntRegion regionToDraw = aIter ? aIter->mDrawRegion
- : aPaintState.mRegionToDraw;
+ // BorrowDrawTargetForRecording doesn't apply the transform, so we have to.
+ RefPtr<DrawTarget> target = capturedState->mTarget;
+ target->SetTransform(capturedState->mTargetTransform);
- // Can't stack allocate refcounted objects.
- RefPtr<CapturedPaintState> capturedPaintState =
- MakeAndAddRef<CapturedPaintState>(regionToDraw,
- mDTBuffer,
- mDTBufferOnWhite,
- Matrix(),
- aPaintState.mMode,
- aPaintState.mContentType);
-
- if (!RotatedContentBuffer::PrepareDrawTargetForPainting(capturedPaintState)) {
+ if (!RotatedContentBuffer::PrepareDrawTargetForPainting(capturedState)) {
return nullptr;
}
- return result;
+ return target;
}
already_AddRefed<SourceSurface>
RotatedContentBuffer::GetSourceSurface(ContextSource aSource) const
{
if (!mDTBuffer || !mDTBuffer->IsValid()) {
gfxCriticalNote << "Invalid buffer in RotatedContentBuffer::GetSourceSurface " << gfx::hexa(mDTBuffer);
return nullptr;
--- a/gfx/layers/RotatedBuffer.h
+++ b/gfx/layers/RotatedBuffer.h
@@ -300,19 +300,19 @@ public:
/**
* Borrow a draw target for recording. The aOutTransform is not applied
* to the returned DrawTarget, BUT it is required to be painting in the right
* location whenever drawing does happen.
*/
RefPtr<CapturedPaintState> BorrowDrawTargetForRecording(PaintState& aPaintState,
DrawIterator* aIter);
- void ExpandDrawRegion(PaintState& aPaintState,
- DrawIterator* aIter,
- gfx::BackendType aBackendType);
+ nsIntRegion ExpandDrawRegion(PaintState& aPaintState,
+ DrawIterator* aIter,
+ gfx::BackendType aBackendType);
static bool PrepareDrawTargetForPainting(CapturedPaintState*);
enum {
BUFFER_COMPONENT_ALPHA = 0x02 // Dual buffers should be created for drawing with
// component alpha.
};
/**
* Return a new surface of |aSize| and |aType|.
--- a/gfx/layers/client/ClientPaintedLayer.cpp
+++ b/gfx/layers/client/ClientPaintedLayer.cpp
@@ -66,22 +66,16 @@ ClientPaintedLayer::CanRecordLayer(Readb
}
// If we have mask layers, we have to render those first
// In this case, don't record for now.
if (GetMaskLayer()) {
return false;
}
- // Component alpha layers aren't supported yet since we have to
- // hold onto both the front/back buffer of a texture client.
- if (GetSurfaceMode() == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
- return false;
- }
-
return GetAncestorMaskLayerCount() == 0;
}
void
ClientPaintedLayer::UpdateContentClient(PaintState& aState)
{
Mutated();