mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
Bug 932888. Remove thebes paths from ThebesLayerBuffer (part 1). r=mattwoodrow
This commit is contained in:
parent
7b5ba9e8ae
commit
176a56a656
@ -26,6 +26,7 @@
|
||||
#include "gfxContext.h"
|
||||
#include "gfxColor.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "Layers.h"
|
||||
#include "SharedTextureImage.h"
|
||||
#include "GLContext.h"
|
||||
@ -814,13 +815,15 @@ PluginInstanceParent::BeginUpdateBackground(const nsIntRect& aRect,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
gfxIntSize sz = mBackground->GetSize();
|
||||
#ifdef DEBUG
|
||||
NS_ABORT_IF_FALSE(nsIntRect(0, 0, sz.width, sz.height).Contains(aRect),
|
||||
"Update outside of background area");
|
||||
#endif
|
||||
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(mBackground);
|
||||
RefPtr<gfx::DrawTarget> dt = gfxPlatform::GetPlatform()->
|
||||
CreateDrawTargetForSurface(mBackground, gfx::IntSize(sz.width, sz.height));
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(dt);
|
||||
*aCtx = ctx.forget().get();
|
||||
|
||||
return NS_OK;
|
||||
|
@ -71,106 +71,6 @@ RotatedBuffer::GetSourceRectangle(XSide aXSide, YSide aYSide) const
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aXSide LEFT means we draw from the left side of the buffer (which
|
||||
* is drawn on the right side of mBufferRect). RIGHT means we draw from
|
||||
* the right side of the buffer (which is drawn on the left side of
|
||||
* mBufferRect).
|
||||
* @param aYSide TOP means we draw from the top side of the buffer (which
|
||||
* is drawn on the bottom side of mBufferRect). BOTTOM means we draw from
|
||||
* the bottom side of the buffer (which is drawn on the top side of
|
||||
* mBufferRect).
|
||||
*/
|
||||
void
|
||||
RotatedBuffer::DrawBufferQuadrant(gfxContext* aTarget,
|
||||
XSide aXSide, YSide aYSide,
|
||||
ContextSource aSource,
|
||||
float aOpacity,
|
||||
gfxASurface* aMask,
|
||||
const gfxMatrix* aMaskTransform) const
|
||||
{
|
||||
// The rectangle that we're going to fill. Basically we're going to
|
||||
// render the buffer at mBufferRect + quadrantTranslation to get the
|
||||
// pixels in the right place, but we're only going to paint within
|
||||
// mBufferRect
|
||||
nsIntRect quadrantRect = GetQuadrantRectangle(aXSide, aYSide);
|
||||
nsIntRect fillRect;
|
||||
if (!fillRect.IntersectRect(mBufferRect, quadrantRect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> source;
|
||||
|
||||
if (aSource == BUFFER_BLACK) {
|
||||
if (mBuffer) {
|
||||
source = mBuffer;
|
||||
} else if (mDTBuffer) {
|
||||
source = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDTBuffer);
|
||||
} else {
|
||||
NS_WARNING("Can't draw a RotatedBuffer without any buffer!");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(aSource == BUFFER_WHITE);
|
||||
if (mBufferOnWhite) {
|
||||
source = mBufferOnWhite;
|
||||
} else if (mDTBufferOnWhite) {
|
||||
source = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDTBufferOnWhite);
|
||||
} else {
|
||||
NS_WARNING("Can't draw a RotatedBuffer without any buffer!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
aTarget->NewPath();
|
||||
aTarget->Rectangle(gfxRect(fillRect.x, fillRect.y,
|
||||
fillRect.width, fillRect.height),
|
||||
true);
|
||||
|
||||
gfxPoint quadrantTranslation(quadrantRect.x, quadrantRect.y);
|
||||
nsRefPtr<gfxPattern> pattern = new gfxPattern(source);
|
||||
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
GraphicsFilter filter = GraphicsFilter::FILTER_NEAREST;
|
||||
pattern->SetFilter(filter);
|
||||
#endif
|
||||
|
||||
gfxContextMatrixAutoSaveRestore saveMatrix(aTarget);
|
||||
|
||||
// Transform from user -> buffer space.
|
||||
gfxMatrix transform;
|
||||
transform.Translate(-quadrantTranslation);
|
||||
|
||||
pattern->SetMatrix(transform);
|
||||
aTarget->SetPattern(pattern);
|
||||
|
||||
if (aMask) {
|
||||
if (aOpacity == 1.0) {
|
||||
aTarget->SetMatrix(*aMaskTransform);
|
||||
aTarget->Mask(aMask);
|
||||
} else {
|
||||
aTarget->PushGroup(GFX_CONTENT_COLOR_ALPHA);
|
||||
aTarget->Paint(aOpacity);
|
||||
aTarget->PopGroupToSource();
|
||||
aTarget->SetMatrix(*aMaskTransform);
|
||||
aTarget->Mask(aMask);
|
||||
}
|
||||
} else {
|
||||
if (aOpacity == 1.0) {
|
||||
aTarget->Fill();
|
||||
} else {
|
||||
aTarget->Save();
|
||||
aTarget->Clip();
|
||||
aTarget->Paint(aOpacity);
|
||||
aTarget->Restore();
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surf = aTarget->CurrentSurface();
|
||||
surf->Flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aXSide LEFT means we draw from the left side of the buffer (which
|
||||
* is drawn on the right side of mBufferRect). RIGHT means we draw from
|
||||
@ -264,21 +164,6 @@ RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget,
|
||||
aTarget->Flush();
|
||||
}
|
||||
|
||||
void
|
||||
RotatedBuffer::DrawBufferWithRotation(gfxContext* aTarget, ContextSource aSource,
|
||||
float aOpacity,
|
||||
gfxASurface* aMask,
|
||||
const gfxMatrix* aMaskTransform) const
|
||||
{
|
||||
PROFILER_LABEL("RotatedBuffer", "DrawBufferWithRotation");
|
||||
// Draw four quadrants. We could use REPEAT_, but it's probably better
|
||||
// not to, to be performance-safe.
|
||||
DrawBufferQuadrant(aTarget, LEFT, TOP, aSource, aOpacity, aMask, aMaskTransform);
|
||||
DrawBufferQuadrant(aTarget, RIGHT, TOP, aSource, aOpacity, aMask, aMaskTransform);
|
||||
DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform);
|
||||
DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform);
|
||||
}
|
||||
|
||||
void
|
||||
RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget, ContextSource aSource,
|
||||
float aOpacity,
|
||||
@ -316,74 +201,42 @@ ThebesLayerBuffer::DrawTo(ThebesLayer* aLayer,
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTarget->IsCairo()) {
|
||||
aTarget->Save();
|
||||
// If the entire buffer is valid, we can just draw the whole thing,
|
||||
// no need to clip. But we'll still clip if clipping is cheap ---
|
||||
// that might let us copy a smaller region of the buffer.
|
||||
// Also clip to the visible region if we're told to.
|
||||
if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
|
||||
(ToData(aLayer)->GetClipToVisibleRegion() &&
|
||||
!aLayer->GetVisibleRegion().Contains(BufferRect())) ||
|
||||
IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
|
||||
// We don't want to draw invalid stuff, so we need to clip. Might as
|
||||
// well clip to the smallest area possible --- the visible region.
|
||||
// Bug 599189 if there is a non-integer-translation transform in aTarget,
|
||||
// we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
|
||||
// and may cause gray lines.
|
||||
gfxUtils::ClipToRegionSnapped(aTarget, aLayer->GetEffectiveVisibleRegion());
|
||||
}
|
||||
RefPtr<DrawTarget> dt = aTarget->GetDrawTarget();
|
||||
MOZ_ASSERT(dt, "Did you pass a non-Azure gfxContext?");
|
||||
bool clipped = false;
|
||||
|
||||
DrawBufferWithRotation(aTarget, BUFFER_BLACK, aOpacity, aMask, aMaskTransform);
|
||||
aTarget->Restore();
|
||||
} else {
|
||||
RefPtr<DrawTarget> dt = aTarget->GetDrawTarget();
|
||||
bool clipped = false;
|
||||
|
||||
// If the entire buffer is valid, we can just draw the whole thing,
|
||||
// no need to clip. But we'll still clip if clipping is cheap ---
|
||||
// that might let us copy a smaller region of the buffer.
|
||||
// Also clip to the visible region if we're told to.
|
||||
if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
|
||||
(ToData(aLayer)->GetClipToVisibleRegion() &&
|
||||
!aLayer->GetVisibleRegion().Contains(BufferRect())) ||
|
||||
IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
|
||||
// We don't want to draw invalid stuff, so we need to clip. Might as
|
||||
// well clip to the smallest area possible --- the visible region.
|
||||
// Bug 599189 if there is a non-integer-translation transform in aTarget,
|
||||
// we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
|
||||
// and may cause gray lines.
|
||||
gfxUtils::ClipToRegionSnapped(dt, aLayer->GetEffectiveVisibleRegion());
|
||||
clipped = true;
|
||||
}
|
||||
|
||||
RefPtr<gfx::SourceSurface> mask;
|
||||
if (aMask) {
|
||||
mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aMask);
|
||||
}
|
||||
|
||||
Matrix maskTransform;
|
||||
if (aMaskTransform) {
|
||||
maskTransform = ToMatrix(*aMaskTransform);
|
||||
}
|
||||
|
||||
CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator());
|
||||
DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform);
|
||||
if (clipped) {
|
||||
dt->PopClip();
|
||||
}
|
||||
// If the entire buffer is valid, we can just draw the whole thing,
|
||||
// no need to clip. But we'll still clip if clipping is cheap ---
|
||||
// that might let us copy a smaller region of the buffer.
|
||||
// Also clip to the visible region if we're told to.
|
||||
if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
|
||||
(ToData(aLayer)->GetClipToVisibleRegion() &&
|
||||
!aLayer->GetVisibleRegion().Contains(BufferRect())) ||
|
||||
IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
|
||||
// We don't want to draw invalid stuff, so we need to clip. Might as
|
||||
// well clip to the smallest area possible --- the visible region.
|
||||
// Bug 599189 if there is a non-integer-translation transform in aTarget,
|
||||
// we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
|
||||
// and may cause gray lines.
|
||||
gfxUtils::ClipToRegionSnapped(dt, aLayer->GetEffectiveVisibleRegion());
|
||||
clipped = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
FillSurface(gfxASurface* aSurface, const nsIntRegion& aRegion,
|
||||
const nsIntPoint& aOffset, const gfxRGBA& aColor)
|
||||
{
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
|
||||
ctx->Translate(-gfxPoint(aOffset.x, aOffset.y));
|
||||
gfxUtils::ClipToRegion(ctx, aRegion);
|
||||
ctx->SetColor(aColor);
|
||||
ctx->Paint();
|
||||
RefPtr<gfx::SourceSurface> mask;
|
||||
if (aMask) {
|
||||
mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aMask);
|
||||
}
|
||||
|
||||
Matrix maskTransform;
|
||||
if (aMaskTransform) {
|
||||
maskTransform = ToMatrix(*aMaskTransform);
|
||||
}
|
||||
|
||||
CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator());
|
||||
DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform);
|
||||
if (clipped) {
|
||||
dt->PopClip();
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfxContext>
|
||||
@ -398,41 +251,17 @@ ThebesLayerBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds, Context
|
||||
if (!EnsureBufferOnWhite()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (mBuffer) {
|
||||
MOZ_ASSERT(mBufferOnWhite);
|
||||
gfxASurface* surfaces[2] = { mBuffer, mBufferOnWhite };
|
||||
nsRefPtr<gfxTeeSurface> surf = new gfxTeeSurface(surfaces, ArrayLength(surfaces));
|
||||
|
||||
// XXX If the device offset is set on the individual surfaces instead of on
|
||||
// the tee surface, we render in the wrong place. Why?
|
||||
gfxPoint deviceOffset = mBuffer->GetDeviceOffset();
|
||||
surfaces[0]->SetDeviceOffset(gfxPoint(0, 0));
|
||||
surfaces[1]->SetDeviceOffset(gfxPoint(0, 0));
|
||||
surf->SetDeviceOffset(deviceOffset);
|
||||
|
||||
surf->SetAllowUseAsSource(false);
|
||||
ctx = new gfxContext(surf);
|
||||
} else {
|
||||
MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
|
||||
RefPtr<DrawTarget> dualDT = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite);
|
||||
ctx = new gfxContext(dualDT);
|
||||
}
|
||||
MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
|
||||
RefPtr<DrawTarget> dualDT = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite);
|
||||
ctx = new gfxContext(dualDT);
|
||||
} else if (aSource == BUFFER_WHITE) {
|
||||
if (!EnsureBufferOnWhite()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (mBufferOnWhite) {
|
||||
ctx = new gfxContext(mBufferOnWhite);
|
||||
} else {
|
||||
ctx = new gfxContext(mDTBufferOnWhite);
|
||||
}
|
||||
ctx = new gfxContext(mDTBufferOnWhite);
|
||||
} else {
|
||||
// BUFFER_BLACK, or BUFFER_BOTH with a single buffer.
|
||||
if (mBuffer) {
|
||||
ctx = new gfxContext(mBuffer);
|
||||
} else {
|
||||
ctx = new gfxContext(mDTBuffer);
|
||||
}
|
||||
ctx = new gfxContext(mDTBuffer);
|
||||
}
|
||||
|
||||
// Figure out which quadrant to draw in
|
||||
@ -454,9 +283,6 @@ ThebesLayerBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds, Context
|
||||
gfxContentType
|
||||
ThebesLayerBuffer::BufferContentType()
|
||||
{
|
||||
if (mBuffer) {
|
||||
return mBuffer->GetContentType();
|
||||
}
|
||||
if (mBufferProvider) {
|
||||
return mBufferProvider->GetContentType();
|
||||
}
|
||||
@ -482,67 +308,38 @@ ThebesLayerBuffer::BufferSizeOkFor(const nsIntSize& aSize)
|
||||
aSize < mBufferRect.Size()));
|
||||
}
|
||||
|
||||
bool
|
||||
ThebesLayerBuffer::IsAzureBuffer()
|
||||
{
|
||||
MOZ_ASSERT(!(mDTBuffer && mBuffer), "Trying to use Azure and Thebes in the same buffer?");
|
||||
if (mDTBuffer) {
|
||||
return true;
|
||||
}
|
||||
if (mBuffer) {
|
||||
return false;
|
||||
}
|
||||
if (mBufferProvider) {
|
||||
return gfxPlatform::GetPlatform()->SupportsAzureContentForType(
|
||||
mBufferProvider->BackendType());
|
||||
}
|
||||
return SupportsAzureContent();
|
||||
}
|
||||
|
||||
bool
|
||||
ThebesLayerBuffer::EnsureBuffer()
|
||||
{
|
||||
if ((!mBuffer && !mDTBuffer) && mBufferProvider) {
|
||||
if (IsAzureBuffer()) {
|
||||
mDTBuffer = mBufferProvider->LockDrawTarget();
|
||||
mBuffer = nullptr;
|
||||
} else {
|
||||
mBuffer = mBufferProvider->LockSurface();
|
||||
mDTBuffer = nullptr;
|
||||
}
|
||||
if (!mDTBuffer && mBufferProvider) {
|
||||
mDTBuffer = mBufferProvider->LockDrawTarget();
|
||||
}
|
||||
|
||||
NS_WARN_IF_FALSE(mBuffer || mDTBuffer, "no buffer");
|
||||
return mBuffer || mDTBuffer;
|
||||
NS_WARN_IF_FALSE(mDTBuffer, "no buffer");
|
||||
return !!mDTBuffer;
|
||||
}
|
||||
|
||||
bool
|
||||
ThebesLayerBuffer::EnsureBufferOnWhite()
|
||||
{
|
||||
if ((!mBufferOnWhite && !mDTBufferOnWhite) && mBufferProviderOnWhite) {
|
||||
if (IsAzureBuffer()) {
|
||||
mDTBufferOnWhite = mBufferProviderOnWhite->LockDrawTarget();
|
||||
mBufferOnWhite = nullptr;
|
||||
} else {
|
||||
mBufferOnWhite = mBufferProviderOnWhite->LockSurface();
|
||||
mDTBufferOnWhite = nullptr;
|
||||
}
|
||||
if (!mDTBufferOnWhite && mBufferProviderOnWhite) {
|
||||
mDTBufferOnWhite = mBufferProviderOnWhite->LockDrawTarget();
|
||||
}
|
||||
|
||||
NS_WARN_IF_FALSE(mBufferOnWhite || mDTBufferOnWhite, "no buffer");
|
||||
return mBufferOnWhite || mDTBufferOnWhite;
|
||||
NS_WARN_IF_FALSE(mDTBufferOnWhite, "no buffer");
|
||||
return mDTBufferOnWhite;
|
||||
}
|
||||
|
||||
bool
|
||||
ThebesLayerBuffer::HaveBuffer() const
|
||||
{
|
||||
return mDTBuffer || mBuffer || mBufferProvider;
|
||||
return mDTBuffer || mBufferProvider;
|
||||
}
|
||||
|
||||
bool
|
||||
ThebesLayerBuffer::HaveBufferOnWhite() const
|
||||
{
|
||||
return mDTBufferOnWhite || mBufferOnWhite || mBufferProviderOnWhite;
|
||||
return mDTBufferOnWhite || mBufferProviderOnWhite;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -680,8 +477,6 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
return result;
|
||||
|
||||
nsIntRect drawBounds = result.mRegionToDraw.GetBounds();
|
||||
nsRefPtr<gfxASurface> destBuffer;
|
||||
nsRefPtr<gfxASurface> destBufferOnWhite;
|
||||
RefPtr<DrawTarget> destDTBuffer;
|
||||
RefPtr<DrawTarget> destDTBufferOnWhite;
|
||||
uint32_t bufferFlags = canHaveRotation ? ALLOW_REPEAT : 0;
|
||||
@ -714,28 +509,16 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
if (mBufferRotation == nsIntPoint(0,0)) {
|
||||
nsIntRect srcRect(nsIntPoint(0, 0), mBufferRect.Size());
|
||||
nsIntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft();
|
||||
if (IsAzureBuffer()) {
|
||||
MOZ_ASSERT(mDTBuffer);
|
||||
mDTBuffer->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
|
||||
IntPoint(dest.x, dest.y));
|
||||
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
||||
if (!EnsureBufferOnWhite()) {
|
||||
return result;
|
||||
}
|
||||
MOZ_ASSERT(mDTBufferOnWhite);
|
||||
mDTBufferOnWhite->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
|
||||
IntPoint(dest.x, dest.y));
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(mBuffer);
|
||||
mBuffer->MovePixels(srcRect, dest);
|
||||
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
||||
if (!EnsureBufferOnWhite()) {
|
||||
return result;
|
||||
}
|
||||
MOZ_ASSERT(mBufferOnWhite);
|
||||
mBufferOnWhite->MovePixels(srcRect, dest);
|
||||
MOZ_ASSERT(mDTBuffer);
|
||||
mDTBuffer->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
|
||||
IntPoint(dest.x, dest.y));
|
||||
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
||||
if (!EnsureBufferOnWhite()) {
|
||||
return result;
|
||||
}
|
||||
MOZ_ASSERT(mDTBufferOnWhite);
|
||||
mDTBufferOnWhite->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
|
||||
IntPoint(dest.x, dest.y));
|
||||
}
|
||||
result.mDidSelfCopy = true;
|
||||
mDidSelfCopy = true;
|
||||
@ -745,50 +528,48 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
} else {
|
||||
// With azure and a data surface perform an buffer unrotate
|
||||
// (SelfCopy).
|
||||
if (IsAzureBuffer()) {
|
||||
unsigned char* data;
|
||||
IntSize size;
|
||||
int32_t stride;
|
||||
SurfaceFormat format;
|
||||
unsigned char* data;
|
||||
IntSize size;
|
||||
int32_t stride;
|
||||
SurfaceFormat format;
|
||||
|
||||
if (mDTBuffer->LockBits(&data, &size, &stride, &format)) {
|
||||
if (mDTBuffer->LockBits(&data, &size, &stride, &format)) {
|
||||
uint8_t bytesPerPixel = BytesPerPixel(format);
|
||||
BufferUnrotate(data,
|
||||
size.width * bytesPerPixel,
|
||||
size.height, stride,
|
||||
newRotation.x * bytesPerPixel, newRotation.y);
|
||||
mDTBuffer->ReleaseBits(data);
|
||||
|
||||
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
||||
if (!EnsureBufferOnWhite()) {
|
||||
return result;
|
||||
}
|
||||
MOZ_ASSERT(mDTBufferOnWhite);
|
||||
mDTBufferOnWhite->LockBits(&data, &size, &stride, &format);
|
||||
uint8_t bytesPerPixel = BytesPerPixel(format);
|
||||
BufferUnrotate(data,
|
||||
size.width * bytesPerPixel,
|
||||
size.height, stride,
|
||||
newRotation.x * bytesPerPixel, newRotation.y);
|
||||
mDTBuffer->ReleaseBits(data);
|
||||
|
||||
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
||||
if (!EnsureBufferOnWhite()) {
|
||||
return result;
|
||||
}
|
||||
MOZ_ASSERT(mDTBufferOnWhite);
|
||||
mDTBufferOnWhite->LockBits(&data, &size, &stride, &format);
|
||||
uint8_t bytesPerPixel = BytesPerPixel(format);
|
||||
BufferUnrotate(data,
|
||||
size.width * bytesPerPixel,
|
||||
size.height, stride,
|
||||
newRotation.x * bytesPerPixel, newRotation.y);
|
||||
mDTBufferOnWhite->ReleaseBits(data);
|
||||
}
|
||||
|
||||
// Buffer unrotate moves all the pixels, note that
|
||||
// we self copied for SyncBackToFrontBuffer
|
||||
result.mDidSelfCopy = true;
|
||||
mDidSelfCopy = true;
|
||||
mBufferRect = destBufferRect;
|
||||
mBufferRotation = nsIntPoint(0, 0);
|
||||
mDTBufferOnWhite->ReleaseBits(data);
|
||||
}
|
||||
|
||||
// Buffer unrotate moves all the pixels, note that
|
||||
// we self copied for SyncBackToFrontBuffer
|
||||
result.mDidSelfCopy = true;
|
||||
mDidSelfCopy = true;
|
||||
mBufferRect = destBufferRect;
|
||||
mBufferRotation = nsIntPoint(0, 0);
|
||||
}
|
||||
|
||||
if (!result.mDidSelfCopy) {
|
||||
destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
|
||||
CreateBuffer(contentType, destBufferRect, bufferFlags,
|
||||
getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite),
|
||||
&destDTBuffer, &destDTBufferOnWhite);
|
||||
if (!destBuffer && !destDTBuffer)
|
||||
if (!destDTBuffer) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -805,10 +586,10 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
} else {
|
||||
// The buffer's not big enough, so allocate a new one
|
||||
CreateBuffer(contentType, destBufferRect, bufferFlags,
|
||||
getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite),
|
||||
&destDTBuffer, &destDTBufferOnWhite);
|
||||
if (!destBuffer && !destDTBuffer)
|
||||
if (!destDTBuffer) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(!(aFlags & PAINT_WILL_RESAMPLE) || destBufferRect == neededRegion.GetBounds(),
|
||||
@ -818,37 +599,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
// and we do not need to clear it below.
|
||||
bool isClear = !HaveBuffer();
|
||||
|
||||
if (destBuffer) {
|
||||
if (!isClear && (mode != Layer::SURFACE_COMPONENT_ALPHA || HaveBufferOnWhite())) {
|
||||
// Copy the bits
|
||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(destBuffer);
|
||||
nsIntPoint offset = -destBufferRect.TopLeft();
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpCtx->Translate(gfxPoint(offset.x, offset.y));
|
||||
if (!EnsureBuffer()) {
|
||||
return result;
|
||||
}
|
||||
DrawBufferWithRotation(tmpCtx, BUFFER_BLACK);
|
||||
|
||||
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
||||
if (!EnsureBufferOnWhite()) {
|
||||
return result;
|
||||
}
|
||||
NS_ASSERTION(destBufferOnWhite, "Must have a white buffer!");
|
||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(destBufferOnWhite);
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpCtx->Translate(gfxPoint(offset.x, offset.y));
|
||||
DrawBufferWithRotation(tmpCtx, BUFFER_WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
mBuffer = destBuffer.forget();
|
||||
mDTBuffer = nullptr;
|
||||
mBufferRect = destBufferRect;
|
||||
mBufferOnWhite = destBufferOnWhite.forget();
|
||||
mDTBufferOnWhite = nullptr;
|
||||
mBufferRotation = nsIntPoint(0,0);
|
||||
} else if (destDTBuffer) {
|
||||
if (destDTBuffer) {
|
||||
if (!isClear && (mode != Layer::SURFACE_COMPONENT_ALPHA || HaveBufferOnWhite())) {
|
||||
// Copy the bits
|
||||
nsIntPoint offset = -destBufferRect.TopLeft();
|
||||
@ -875,9 +626,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
}
|
||||
|
||||
mDTBuffer = destDTBuffer.forget();
|
||||
mBuffer = nullptr;
|
||||
mDTBufferOnWhite = destDTBufferOnWhite.forget();
|
||||
mBufferOnWhite = nullptr;
|
||||
mBufferRect = destBufferRect;
|
||||
mBufferRotation = nsIntPoint(0,0);
|
||||
}
|
||||
@ -893,37 +642,20 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
result.mClip = CLIP_DRAW_SNAPPED;
|
||||
|
||||
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
||||
if (IsAzureBuffer()) {
|
||||
MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
|
||||
nsIntRegionRectIterator iter(result.mRegionToDraw);
|
||||
const nsIntRect *iterRect;
|
||||
while ((iterRect = iter.Next())) {
|
||||
mDTBuffer->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
|
||||
ColorPattern(Color(0.0, 0.0, 0.0, 1.0)));
|
||||
mDTBufferOnWhite->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
|
||||
ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(mBuffer && mBufferOnWhite);
|
||||
FillSurface(mBuffer, result.mRegionToDraw, topLeft, gfxRGBA(0.0, 0.0, 0.0, 1.0));
|
||||
FillSurface(mBufferOnWhite, result.mRegionToDraw, topLeft, gfxRGBA(1.0, 1.0, 1.0, 1.0));
|
||||
MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
|
||||
nsIntRegionRectIterator iter(result.mRegionToDraw);
|
||||
const nsIntRect *iterRect;
|
||||
while ((iterRect = iter.Next())) {
|
||||
mDTBuffer->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
|
||||
ColorPattern(Color(0.0, 0.0, 0.0, 1.0)));
|
||||
mDTBufferOnWhite->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
|
||||
ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
|
||||
}
|
||||
} else if (contentType == GFX_CONTENT_COLOR_ALPHA && !isClear) {
|
||||
if (IsAzureBuffer()) {
|
||||
nsIntRegionRectIterator iter(result.mRegionToDraw);
|
||||
const nsIntRect *iterRect;
|
||||
while ((iterRect = iter.Next())) {
|
||||
result.mContext->GetDrawTarget()->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
|
||||
}
|
||||
// Clear will do something expensive with a complex clip pushed, so clip
|
||||
// here.
|
||||
} else {
|
||||
MOZ_ASSERT(result.mContext->IsCairo());
|
||||
result.mContext->Save();
|
||||
gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
|
||||
result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
result.mContext->Paint();
|
||||
result.mContext->Restore();
|
||||
nsIntRegionRectIterator iter(result.mRegionToDraw);
|
||||
const nsIntRect *iterRect;
|
||||
while ((iterRect = iter.Next())) {
|
||||
result.mContext->GetDrawTarget()->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,15 +55,6 @@ class RotatedBuffer {
|
||||
public:
|
||||
typedef gfxContentType ContentType;
|
||||
|
||||
RotatedBuffer(gfxASurface* aBuffer, gfxASurface* aBufferOnWhite,
|
||||
const nsIntRect& aBufferRect,
|
||||
const nsIntPoint& aBufferRotation)
|
||||
: mBuffer(aBuffer)
|
||||
, mBufferOnWhite(aBufferOnWhite)
|
||||
, mBufferRect(aBufferRect)
|
||||
, mBufferRotation(aBufferRotation)
|
||||
, mDidSelfCopy(false)
|
||||
{ }
|
||||
RotatedBuffer(gfx::DrawTarget* aDTBuffer, gfx::DrawTarget* aDTBufferOnWhite,
|
||||
const nsIntRect& aBufferRect,
|
||||
const nsIntPoint& aBufferRotation)
|
||||
@ -85,11 +76,6 @@ public:
|
||||
BUFFER_WHITE, // The buffer with white background, only valid with component alpha.
|
||||
BUFFER_BOTH // The combined black/white buffers, only valid for writing operations, not reading.
|
||||
};
|
||||
void DrawBufferWithRotation(gfxContext* aTarget, ContextSource aSource,
|
||||
float aOpacity = 1.0,
|
||||
gfxASurface* aMask = nullptr,
|
||||
const gfxMatrix* aMaskTransform = nullptr) const;
|
||||
|
||||
void DrawBufferWithRotation(gfx::DrawTarget* aTarget, ContextSource aSource,
|
||||
float aOpacity = 1.0,
|
||||
gfx::CompositionOp aOperator = gfx::OP_OVER,
|
||||
@ -104,8 +90,8 @@ public:
|
||||
const nsIntRect& BufferRect() const { return mBufferRect; }
|
||||
const nsIntPoint& BufferRotation() const { return mBufferRotation; }
|
||||
|
||||
virtual bool HaveBuffer() const { return mBuffer || mDTBuffer; }
|
||||
virtual bool HaveBufferOnWhite() const { return mBufferOnWhite || mDTBufferOnWhite; }
|
||||
virtual bool HaveBuffer() const { return mDTBuffer; }
|
||||
virtual bool HaveBufferOnWhite() const { return mDTBufferOnWhite; }
|
||||
|
||||
protected:
|
||||
|
||||
@ -124,11 +110,6 @@ protected:
|
||||
* buffer. aMaskTransform must be non-null if aMask is non-null, and is used
|
||||
* to adjust the coordinate space of the mask.
|
||||
*/
|
||||
void DrawBufferQuadrant(gfxContext* aTarget, XSide aXSide, YSide aYSide,
|
||||
ContextSource aSource,
|
||||
float aOpacity,
|
||||
gfxASurface* aMask,
|
||||
const gfxMatrix* aMaskTransform) const;
|
||||
void DrawBufferQuadrant(gfx::DrawTarget* aTarget, XSide aXSide, YSide aYSide,
|
||||
ContextSource aSource,
|
||||
float aOpacity,
|
||||
@ -136,8 +117,6 @@ protected:
|
||||
gfx::SourceSurface* aMask,
|
||||
const gfx::Matrix* aMaskTransform) const;
|
||||
|
||||
nsRefPtr<gfxASurface> mBuffer;
|
||||
nsRefPtr<gfxASurface> mBufferOnWhite;
|
||||
RefPtr<gfx::DrawTarget> mDTBuffer;
|
||||
RefPtr<gfx::DrawTarget> mDTBufferOnWhite;
|
||||
/** The area of the ThebesLayer that is covered by the buffer as a whole */
|
||||
@ -196,8 +175,6 @@ public:
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
mBuffer = nullptr;
|
||||
mBufferOnWhite = nullptr;
|
||||
mDTBuffer = nullptr;
|
||||
mDTBufferOnWhite = nullptr;
|
||||
mBufferProvider = nullptr;
|
||||
@ -264,18 +241,13 @@ public:
|
||||
*/
|
||||
virtual void
|
||||
CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
|
||||
gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface,
|
||||
RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) = 0;
|
||||
virtual bool SupportsAzureContent() const
|
||||
{ return false; }
|
||||
|
||||
/**
|
||||
* Get the underlying buffer, if any. This is useful because we can pass
|
||||
* in the buffer as the default "reference surface" if there is one.
|
||||
* Don't use it for anything else!
|
||||
*/
|
||||
gfxASurface* GetBuffer() { return mBuffer; }
|
||||
gfxASurface* GetBufferOnWhite() { return mBufferOnWhite; }
|
||||
gfx::DrawTarget* GetDTBuffer() { return mDTBuffer; }
|
||||
gfx::DrawTarget* GetDTBufferOnWhite() { return mDTBufferOnWhite; }
|
||||
|
||||
@ -288,35 +260,11 @@ public:
|
||||
gfxASurface* aMask, const gfxMatrix* aMaskTransform);
|
||||
|
||||
protected:
|
||||
// If this buffer is currently using Azure.
|
||||
bool IsAzureBuffer();
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
SetBuffer(gfxASurface* aBuffer,
|
||||
const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsAzureContent());
|
||||
nsRefPtr<gfxASurface> tmp = mBuffer.forget();
|
||||
mBuffer = aBuffer;
|
||||
mBufferRect = aBufferRect;
|
||||
mBufferRotation = aBufferRotation;
|
||||
return tmp.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
SetBufferOnWhite(gfxASurface* aBuffer)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsAzureContent());
|
||||
nsRefPtr<gfxASurface> tmp = mBufferOnWhite.forget();
|
||||
mBufferOnWhite = aBuffer;
|
||||
return tmp.forget();
|
||||
}
|
||||
|
||||
TemporaryRef<gfx::DrawTarget>
|
||||
SetDTBuffer(gfx::DrawTarget* aBuffer,
|
||||
const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation)
|
||||
const nsIntRect& aBufferRect,
|
||||
const nsIntPoint& aBufferRotation)
|
||||
{
|
||||
MOZ_ASSERT(SupportsAzureContent());
|
||||
RefPtr<gfx::DrawTarget> tmp = mDTBuffer.forget();
|
||||
mDTBuffer = aBuffer;
|
||||
mBufferRect = aBufferRect;
|
||||
@ -327,7 +275,6 @@ protected:
|
||||
TemporaryRef<gfx::DrawTarget>
|
||||
SetDTBufferOnWhite(gfx::DrawTarget* aBuffer)
|
||||
{
|
||||
MOZ_ASSERT(SupportsAzureContent());
|
||||
RefPtr<gfx::DrawTarget> tmp = mDTBufferOnWhite.forget();
|
||||
mDTBufferOnWhite = aBuffer;
|
||||
return tmp.forget();
|
||||
@ -348,11 +295,10 @@ protected:
|
||||
{
|
||||
// Only this buffer provider can give us a buffer. If we
|
||||
// already have one, something has gone wrong.
|
||||
MOZ_ASSERT(!aClient || (!mBuffer && !mDTBuffer));
|
||||
MOZ_ASSERT(!aClient || !mDTBuffer);
|
||||
|
||||
mBufferProvider = aClient;
|
||||
if (!mBufferProvider) {
|
||||
mBuffer = nullptr;
|
||||
mDTBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
@ -361,11 +307,10 @@ protected:
|
||||
{
|
||||
// Only this buffer provider can give us a buffer. If we
|
||||
// already have one, something has gone wrong.
|
||||
MOZ_ASSERT(!aClient || (!mBufferOnWhite && !mDTBufferOnWhite));
|
||||
MOZ_ASSERT(!aClient || !mDTBufferOnWhite);
|
||||
|
||||
mBufferProviderOnWhite = aClient;
|
||||
if (!mBufferProviderOnWhite) {
|
||||
mBufferOnWhite = nullptr;
|
||||
mDTBufferOnWhite = nullptr;
|
||||
}
|
||||
}
|
||||
@ -382,9 +327,6 @@ protected:
|
||||
static bool IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion);
|
||||
|
||||
protected:
|
||||
// Buffer helpers. Don't use mBuffer directly; instead use one of
|
||||
// these helpers.
|
||||
|
||||
/**
|
||||
* Return the buffer's content type. Requires a valid buffer or
|
||||
* buffer provider.
|
||||
|
@ -82,37 +82,17 @@ void
|
||||
ContentClientBasic::CreateBuffer(ContentType aType,
|
||||
const nsIntRect& aRect,
|
||||
uint32_t aFlags,
|
||||
gfxASurface** aBlackSurface,
|
||||
gfxASurface** aWhiteSurface,
|
||||
RefPtr<gfx::DrawTarget>* aBlackDT,
|
||||
RefPtr<gfx::DrawTarget>* aWhiteDT)
|
||||
{
|
||||
MOZ_ASSERT(!(aFlags & BUFFER_COMPONENT_ALPHA));
|
||||
if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
|
||||
gfxImageFormat format =
|
||||
gfxPlatform::GetPlatform()->OptimalFormatForContent(aType);
|
||||
MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
|
||||
gfxImageFormat format =
|
||||
gfxPlatform::GetPlatform()->OptimalFormatForContent(aType);
|
||||
|
||||
*aBlackDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
|
||||
IntSize(aRect.width, aRect.height),
|
||||
ImageFormatToSurfaceFormat(format));
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> referenceSurface = GetBuffer();
|
||||
if (!referenceSurface) {
|
||||
gfxContext* defaultTarget = mManager->GetDefaultTarget();
|
||||
if (defaultTarget) {
|
||||
referenceSurface = defaultTarget->CurrentSurface();
|
||||
} else {
|
||||
nsIWidget* widget = mManager->GetRetainerWidget();
|
||||
if (!widget || !(referenceSurface = widget->GetThebesSurface())) {
|
||||
referenceSurface = mManager->GetTarget()->CurrentSurface();
|
||||
}
|
||||
}
|
||||
}
|
||||
nsRefPtr<gfxASurface> ret = referenceSurface->CreateSimilarSurface(
|
||||
aType, gfxIntSize(aRect.width, aRect.height));
|
||||
*aBlackSurface = ret.forget().get();
|
||||
*aBlackDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
|
||||
IntSize(aRect.width, aRect.height),
|
||||
ImageFormatToSurfaceFormat(format));
|
||||
}
|
||||
|
||||
void
|
||||
@ -219,27 +199,10 @@ ContentClientRemoteBuffer::BuildDeprecatedTextureClients(ContentType aType,
|
||||
mIsNewBuffer = true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentClientBasic::SupportsAzureContent() const
|
||||
{
|
||||
return gfxPlatform::GetPlatform()->SupportsAzureContent();
|
||||
}
|
||||
|
||||
bool
|
||||
ContentClientRemoteBuffer::SupportsAzureContent() const
|
||||
{
|
||||
MOZ_ASSERT(mDeprecatedTextureClient);
|
||||
|
||||
return gfxPlatform::GetPlatform()->SupportsAzureContentForType(
|
||||
mDeprecatedTextureClient->BackendType());
|
||||
}
|
||||
|
||||
void
|
||||
ContentClientRemoteBuffer::CreateBuffer(ContentType aType,
|
||||
const nsIntRect& aRect,
|
||||
uint32_t aFlags,
|
||||
gfxASurface** aBlackSurface,
|
||||
gfxASurface** aWhiteSurface,
|
||||
RefPtr<gfx::DrawTarget>* aBlackDT,
|
||||
RefPtr<gfx::DrawTarget>* aWhiteDT)
|
||||
{
|
||||
@ -248,19 +211,11 @@ ContentClientRemoteBuffer::CreateBuffer(ContentType aType,
|
||||
return;
|
||||
}
|
||||
|
||||
if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(
|
||||
mDeprecatedTextureClient->BackendType())) {
|
||||
*aBlackDT = mDeprecatedTextureClient->LockDrawTarget();
|
||||
if (aFlags & BUFFER_COMPONENT_ALPHA) {
|
||||
*aWhiteDT = mDeprecatedTextureClientOnWhite->LockDrawTarget();
|
||||
}
|
||||
} else {
|
||||
nsRefPtr<gfxASurface> ret = mDeprecatedTextureClient->LockSurface();
|
||||
*aBlackSurface = ret.forget().get();
|
||||
if (aFlags & BUFFER_COMPONENT_ALPHA) {
|
||||
nsRefPtr<gfxASurface> retWhite = mDeprecatedTextureClientOnWhite->LockSurface();
|
||||
*aWhiteSurface = retWhite.forget().get();
|
||||
}
|
||||
MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContentForType(
|
||||
mDeprecatedTextureClient->BackendType()));
|
||||
*aBlackDT = mDeprecatedTextureClient->LockDrawTarget();
|
||||
if (aFlags & BUFFER_COMPONENT_ALPHA) {
|
||||
*aWhiteDT = mDeprecatedTextureClientOnWhite->LockDrawTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,15 +426,6 @@ struct AutoDeprecatedTextureClient {
|
||||
mTexture->Unlock();
|
||||
}
|
||||
}
|
||||
gfxASurface* GetSurface(DeprecatedTextureClient* aTexture)
|
||||
{
|
||||
MOZ_ASSERT(!mTexture);
|
||||
mTexture = aTexture;
|
||||
if (mTexture) {
|
||||
return mTexture->LockSurface();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
DrawTarget* GetDrawTarget(DeprecatedTextureClient* aTexture)
|
||||
{
|
||||
MOZ_ASSERT(!mTexture);
|
||||
@ -536,25 +482,15 @@ ContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
|
||||
|
||||
AutoDeprecatedTextureClient autoTextureFront;
|
||||
AutoDeprecatedTextureClient autoTextureFrontOnWhite;
|
||||
if (SupportsAzureContent()) {
|
||||
// We need to ensure that we lock these two buffers in the same
|
||||
// order as the compositor to prevent deadlocks.
|
||||
DrawTarget* dt = autoTextureFront.GetDrawTarget(mFrontClient);
|
||||
DrawTarget* dtOnWhite = autoTextureFrontOnWhite.GetDrawTarget(mFrontClientOnWhite);
|
||||
RotatedBuffer frontBuffer(dt,
|
||||
dtOnWhite,
|
||||
mFrontBufferRect,
|
||||
mFrontBufferRotation);
|
||||
UpdateDestinationFrom(frontBuffer, updateRegion);
|
||||
} else {
|
||||
gfxASurface* surf = autoTextureFront.GetSurface(mFrontClient);
|
||||
gfxASurface* surfOnWhite = autoTextureFrontOnWhite.GetSurface(mFrontClientOnWhite);
|
||||
RotatedBuffer frontBuffer(surf,
|
||||
surfOnWhite,
|
||||
mFrontBufferRect,
|
||||
mFrontBufferRotation);
|
||||
UpdateDestinationFrom(frontBuffer, updateRegion);
|
||||
}
|
||||
// We need to ensure that we lock these two buffers in the same
|
||||
// order as the compositor to prevent deadlocks.
|
||||
DrawTarget* dt = autoTextureFront.GetDrawTarget(mFrontClient);
|
||||
DrawTarget* dtOnWhite = autoTextureFrontOnWhite.GetDrawTarget(mFrontClientOnWhite);
|
||||
RotatedBuffer frontBuffer(dt,
|
||||
dtOnWhite,
|
||||
mFrontBufferRect,
|
||||
mFrontBufferRotation);
|
||||
UpdateDestinationFrom(frontBuffer, updateRegion);
|
||||
|
||||
mFrontAndBackBufferDiffer = false;
|
||||
}
|
||||
@ -575,12 +511,7 @@ ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
|
||||
gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
|
||||
}
|
||||
|
||||
if (SupportsAzureContent()) {
|
||||
MOZ_ASSERT(!destCtx->IsCairo());
|
||||
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
|
||||
} else {
|
||||
aSource.DrawBufferWithRotation(destCtx, BUFFER_BLACK);
|
||||
}
|
||||
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
|
||||
|
||||
if (aSource.HaveBufferOnWhite()) {
|
||||
MOZ_ASSERT(HaveBufferOnWhite());
|
||||
@ -593,12 +524,7 @@ ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
|
||||
gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
|
||||
}
|
||||
|
||||
if (SupportsAzureContent()) {
|
||||
MOZ_ASSERT(!destCtx->IsCairo());
|
||||
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
|
||||
} else {
|
||||
aSource.DrawBufferWithRotation(destCtx, BUFFER_WHITE);
|
||||
}
|
||||
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,57 +556,30 @@ ContentClientSingleBuffered::SyncFrontBufferToBackBuffer()
|
||||
}
|
||||
mFrontAndBackBufferDiffer = false;
|
||||
|
||||
if (SupportsAzureContent()) {
|
||||
DrawTarget* backBuffer = GetDTBuffer();
|
||||
if (!backBuffer && mDeprecatedTextureClient) {
|
||||
backBuffer = mDeprecatedTextureClient->LockDrawTarget();
|
||||
}
|
||||
if (!backBuffer) {
|
||||
NS_WARNING("Could not lock texture client");
|
||||
return;
|
||||
}
|
||||
DrawTarget* backBuffer = GetDTBuffer();
|
||||
if (!backBuffer && mDeprecatedTextureClient) {
|
||||
backBuffer = mDeprecatedTextureClient->LockDrawTarget();
|
||||
}
|
||||
if (!backBuffer) {
|
||||
NS_WARNING("Could not lock texture client");
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> oldBuffer;
|
||||
oldBuffer = SetDTBuffer(backBuffer,
|
||||
mBufferRect,
|
||||
mBufferRotation);
|
||||
|
||||
backBuffer = GetDTBufferOnWhite();
|
||||
if (!backBuffer && mDeprecatedTextureClientOnWhite) {
|
||||
backBuffer = mDeprecatedTextureClientOnWhite->LockDrawTarget();
|
||||
}
|
||||
if (!backBuffer) {
|
||||
NS_WARNING("Could not lock texture client (on white)");
|
||||
return;
|
||||
}
|
||||
|
||||
oldBuffer = SetDTBufferOnWhite(backBuffer);
|
||||
} else {
|
||||
gfxASurface* backBuffer = GetBuffer();
|
||||
if (!backBuffer && mDeprecatedTextureClient) {
|
||||
backBuffer = mDeprecatedTextureClient->LockSurface();
|
||||
}
|
||||
if (!backBuffer) {
|
||||
NS_WARNING("Could not lock texture client");
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> oldBuffer;
|
||||
oldBuffer = SetBuffer(backBuffer,
|
||||
RefPtr<DrawTarget> oldBuffer;
|
||||
oldBuffer = SetDTBuffer(backBuffer,
|
||||
mBufferRect,
|
||||
mBufferRotation);
|
||||
|
||||
backBuffer = GetBufferOnWhite();
|
||||
if (!backBuffer && mDeprecatedTextureClientOnWhite) {
|
||||
backBuffer = mDeprecatedTextureClientOnWhite->LockSurface();
|
||||
}
|
||||
if (!backBuffer) {
|
||||
NS_WARNING("Could not lock texture client (on white)");
|
||||
return;
|
||||
}
|
||||
|
||||
oldBuffer = SetBufferOnWhite(backBuffer);
|
||||
backBuffer = GetDTBufferOnWhite();
|
||||
if (!backBuffer && mDeprecatedTextureClientOnWhite) {
|
||||
backBuffer = mDeprecatedTextureClientOnWhite->LockDrawTarget();
|
||||
}
|
||||
if (!backBuffer) {
|
||||
NS_WARNING("Could not lock texture client (on white)");
|
||||
return;
|
||||
}
|
||||
|
||||
oldBuffer = SetDTBufferOnWhite(backBuffer);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -900,39 +799,19 @@ ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
|
||||
"BeginUpdate should always modify the draw region in the same way!");
|
||||
FillSurface(onBlack, result.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(0.0, 0.0, 0.0, 1.0));
|
||||
FillSurface(onWhite, result.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(1.0, 1.0, 1.0, 1.0));
|
||||
if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
|
||||
RefPtr<DrawTarget> onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize());
|
||||
RefPtr<DrawTarget> onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize());
|
||||
RefPtr<DrawTarget> dt = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
|
||||
result.mContext = new gfxContext(dt);
|
||||
} else {
|
||||
gfxASurface* surfaces[2] = { onBlack.get(), onWhite.get() };
|
||||
nsRefPtr<gfxTeeSurface> surf = new gfxTeeSurface(surfaces, ArrayLength(surfaces));
|
||||
|
||||
// XXX If the device offset is set on the individual surfaces instead of on
|
||||
// the tee surface, we render in the wrong place. Why?
|
||||
gfxPoint deviceOffset = onBlack->GetDeviceOffset();
|
||||
onBlack->SetDeviceOffset(gfxPoint(0, 0));
|
||||
onWhite->SetDeviceOffset(gfxPoint(0, 0));
|
||||
surf->SetDeviceOffset(deviceOffset);
|
||||
|
||||
// Using this surface as a source will likely go horribly wrong, since
|
||||
// only the onBlack surface will really be used, so alpha information will
|
||||
// be incorrect.
|
||||
surf->SetAllowUseAsSource(false);
|
||||
result.mContext = new gfxContext(surf);
|
||||
}
|
||||
MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
|
||||
RefPtr<DrawTarget> onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize());
|
||||
RefPtr<DrawTarget> onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize());
|
||||
RefPtr<DrawTarget> dt = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
|
||||
result.mContext = new gfxContext(dt);
|
||||
} else {
|
||||
result.mContext = nullptr;
|
||||
}
|
||||
} else {
|
||||
nsRefPtr<gfxASurface> surf = GetUpdateSurface(BUFFER_BLACK, result.mRegionToDraw);
|
||||
if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
|
||||
RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize());
|
||||
result.mContext = new gfxContext(dt);
|
||||
} else {
|
||||
result.mContext = new gfxContext(surf);
|
||||
}
|
||||
MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
|
||||
RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize());
|
||||
result.mContext = new gfxContext(dt);
|
||||
}
|
||||
if (!result.mContext) {
|
||||
NS_WARNING("unable to get context for update");
|
||||
|
@ -154,9 +154,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
|
||||
gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface,
|
||||
RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) MOZ_OVERRIDE;
|
||||
virtual bool SupportsAzureContent() const;
|
||||
|
||||
virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE
|
||||
{
|
||||
@ -237,11 +235,8 @@ public:
|
||||
}
|
||||
|
||||
virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
|
||||
gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface,
|
||||
RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool SupportsAzureContent() const MOZ_OVERRIDE;
|
||||
|
||||
void DestroyBuffers();
|
||||
|
||||
virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE
|
||||
|
Loading…
Reference in New Issue
Block a user