Bug 750434 - Add support for Azure content rendering to ClientTiledThebesLayer. r=mattwoodrow,BenWa

This commit is contained in:
Anthony Jones ext:(%2C%20George%20Wright%20%3Cgwright%40mozilla.com%3E) 2013-08-14 16:31:05 +12:00
parent a9bc091490
commit c4ddbf3f59
3 changed files with 82 additions and 21 deletions

View File

@ -233,16 +233,34 @@ BasicTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
*/ */
if (useSinglePaintBuffer) { if (useSinglePaintBuffer) {
nsRefPtr<gfxContext> ctxt;
const nsIntRect bounds = aPaintRegion.GetBounds(); const nsIntRect bounds = aPaintRegion.GetBounds();
{ {
PROFILER_LABEL("BasicTiledLayerBuffer", "PaintThebesSingleBufferAlloc"); PROFILER_LABEL("BasicTiledLayerBuffer", "PaintThebesSingleBufferAlloc");
gfxASurface::gfxImageFormat format =
gfxPlatform::GetPlatform()->OptimalFormatForContent(
GetContentType());
if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
mSinglePaintDrawTarget =
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
gfx::IntSize(ceilf(bounds.width * mResolution),
ceilf(bounds.height * mResolution)),
gfx::ImageFormatToSurfaceFormat(format));
ctxt = new gfxContext(mSinglePaintDrawTarget);
} else {
mSinglePaintBuffer = new gfxImageSurface( mSinglePaintBuffer = new gfxImageSurface(
gfxIntSize(ceilf(bounds.width * mResolution), gfxIntSize(ceilf(bounds.width * mResolution),
ceilf(bounds.height * mResolution)), ceilf(bounds.height * mResolution)),
gfxPlatform::GetPlatform()->OptimalFormatForContent(GetContentType()), !mThebesLayer->CanUseOpaqueSurface()); format,
!mThebesLayer->CanUseOpaqueSurface());
ctxt = new gfxContext(mSinglePaintBuffer);
}
mSinglePaintBufferOffset = nsIntPoint(bounds.x, bounds.y); mSinglePaintBufferOffset = nsIntPoint(bounds.x, bounds.y);
} }
nsRefPtr<gfxContext> ctxt = new gfxContext(mSinglePaintBuffer);
ctxt->NewPath(); ctxt->NewPath();
ctxt->Scale(mResolution, mResolution); ctxt->Scale(mResolution, mResolution);
ctxt->Translate(gfxPoint(-bounds.x, -bounds.y)); ctxt->Translate(gfxPoint(-bounds.x, -bounds.y));
@ -286,6 +304,7 @@ BasicTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
mCallback = nullptr; mCallback = nullptr;
mCallbackData = nullptr; mCallbackData = nullptr;
mSinglePaintBuffer = nullptr; mSinglePaintBuffer = nullptr;
mSinglePaintDrawTarget = nullptr;
} }
BasicTiledLayerTile BasicTiledLayerTile
@ -299,24 +318,61 @@ BasicTiledLayerBuffer::ValidateTileInternal(BasicTiledLayerTile aTile,
aTile.mDeprecatedTextureClient = static_cast<DeprecatedTextureClientTile*>(textureClient.get()); aTile.mDeprecatedTextureClient = static_cast<DeprecatedTextureClientTile*>(textureClient.get());
} }
aTile.mDeprecatedTextureClient->EnsureAllocated(gfx::IntSize(GetTileLength(), GetTileLength()), GetContentType()); aTile.mDeprecatedTextureClient->EnsureAllocated(gfx::IntSize(GetTileLength(), GetTileLength()), GetContentType());
gfxASurface* writableSurface = aTile.mDeprecatedTextureClient->LockImageSurface(); gfxImageSurface* writableSurface = aTile.mDeprecatedTextureClient->LockImageSurface();
// Bug 742100, this gfxContext really should live on the stack. // Bug 742100, this gfxContext really should live on the stack.
nsRefPtr<gfxContext> ctxt = new gfxContext(writableSurface); nsRefPtr<gfxContext> ctxt;
RefPtr<gfx::DrawTarget> writableDrawTarget;
if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
// TODO: Instead of creating a gfxImageSurface to back the tile we should
// create an offscreen DrawTarget. This would need to be shared cross-thread
// and support copy on write semantics.
gfx::SurfaceFormat format =
gfx::ImageFormatToSurfaceFormat(writableSurface->Format());
writableDrawTarget =
gfxPlatform::GetPlatform()->CreateDrawTargetForData(
writableSurface->Data(),
gfx::IntSize(writableSurface->Width(), writableSurface->Height()),
writableSurface->Stride(),
format);
ctxt = new gfxContext(writableDrawTarget);
} else {
ctxt = new gfxContext(writableSurface);
ctxt->SetOperator(gfxContext::OPERATOR_SOURCE);
}
if (mSinglePaintBuffer) {
gfxRect drawRect(aDirtyRect.x - aTileOrigin.x, aDirtyRect.y - aTileOrigin.y, gfxRect drawRect(aDirtyRect.x - aTileOrigin.x, aDirtyRect.y - aTileOrigin.y,
aDirtyRect.width, aDirtyRect.height); aDirtyRect.width, aDirtyRect.height);
ctxt->SetOperator(gfxContext::OPERATOR_SOURCE); if (mSinglePaintBuffer || mSinglePaintDrawTarget) {
if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
gfx::Rect drawRect(aDirtyRect.x - aTileOrigin.x,
aDirtyRect.y - aTileOrigin.y,
aDirtyRect.width,
aDirtyRect.height);
drawRect.Scale(mResolution);
RefPtr<gfx::SourceSurface> source = mSinglePaintDrawTarget->Snapshot();
writableDrawTarget->CopySurface(
source,
gfx::IntRect(roundf((aDirtyRect.x - mSinglePaintBufferOffset.x) * mResolution),
roundf((aDirtyRect.y - mSinglePaintBufferOffset.y) * mResolution),
drawRect.width,
drawRect.height),
gfx::IntPoint(roundf(drawRect.x), roundf(drawRect.y)));
} else {
gfxRect drawRect(aDirtyRect.x - aTileOrigin.x, aDirtyRect.y - aTileOrigin.y,
aDirtyRect.width, aDirtyRect.height);
drawRect.Scale(mResolution, mResolution);
ctxt->NewPath(); ctxt->NewPath();
ctxt->SetSource(mSinglePaintBuffer.get(), ctxt->SetSource(mSinglePaintBuffer.get(),
gfxPoint((mSinglePaintBufferOffset.x - aDirtyRect.x + drawRect.x) * gfxPoint((mSinglePaintBufferOffset.x - aDirtyRect.x) * mResolution + drawRect.x,
mResolution, (mSinglePaintBufferOffset.y - aDirtyRect.y) * mResolution + drawRect.y));
(mSinglePaintBufferOffset.y - aDirtyRect.y + drawRect.y) * ctxt->SnappedRectangle(drawRect);
mResolution));
drawRect.Scale(mResolution, mResolution);
ctxt->Rectangle(drawRect, true);
ctxt->Fill(); ctxt->Fill();
}
} else { } else {
ctxt->NewPath(); ctxt->NewPath();
ctxt->Scale(mResolution, mResolution); ctxt->Scale(mResolution, mResolution);

View File

@ -230,6 +230,7 @@ private:
// The buffer we use when UseSinglePaintBuffer() above is true. // The buffer we use when UseSinglePaintBuffer() above is true.
nsRefPtr<gfxImageSurface> mSinglePaintBuffer; nsRefPtr<gfxImageSurface> mSinglePaintBuffer;
RefPtr<gfx::DrawTarget> mSinglePaintDrawTarget;
nsIntPoint mSinglePaintBufferOffset; nsIntPoint mSinglePaintBufferOffset;
BasicTiledLayerTile ValidateTileInternal(BasicTiledLayerTile aTile, BasicTiledLayerTile ValidateTileInternal(BasicTiledLayerTile aTile,

View File

@ -903,8 +903,12 @@ gfxPlatform::CreateOffscreenContentDrawTarget(const IntSize& aSize, SurfaceForma
RefPtr<DrawTarget> RefPtr<DrawTarget>
gfxPlatform::CreateDrawTargetForData(unsigned char* aData, const IntSize& aSize, int32_t aStride, SurfaceFormat aFormat) gfxPlatform::CreateDrawTargetForData(unsigned char* aData, const IntSize& aSize, int32_t aStride, SurfaceFormat aFormat)
{ {
NS_ASSERTION(mPreferredCanvasBackend, "No backend."); NS_ASSERTION(mContentBackend, "No backend.");
return Factory::CreateDrawTargetForData(mPreferredCanvasBackend, aData, aSize, aStride, aFormat); if (mContentBackend == BACKEND_CAIRO) {
nsRefPtr<gfxImageSurface> image = new gfxImageSurface(aData, gfxIntSize(aSize.width, aSize.height), aStride, SurfaceFormatToImageFormat(aFormat));
return Factory::CreateDrawTargetForCairoSurface(image->CairoSurface(), aSize);
}
return Factory::CreateDrawTargetForData(mContentBackend, aData, aSize, aStride, aFormat);
} }
/* static */ BackendType /* static */ BackendType