зеркало из https://github.com/mozilla/gecko-dev.git
Bug 765734, part 4: Add an RAII helper to open/close SurfaceDescriptors and mark usage of SurfaceDescriptor as ReadOnly or ReadWrite. r=BenWa,nrc sr=roc
--HG-- extra : rebase_source : 34d9f4f021bac540e96b82eceb855c9c2ce59ce6
This commit is contained in:
Родитель
1ce07b9102
Коммит
54accca6a3
|
@ -171,6 +171,16 @@ protected:
|
|||
return tmp.forget();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the buffer only. This is intended to be used with the
|
||||
* shadow-layer Open/CloseDescriptor interface, to ensure we don't
|
||||
* accidentally touch a buffer when it's not mapped.
|
||||
*/
|
||||
void SetBuffer(gfxASurface* aBuffer)
|
||||
{
|
||||
mBuffer = aBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a context at the specified resolution for updating |aBounds|,
|
||||
* which must be contained within a single quadrant.
|
||||
|
|
|
@ -47,10 +47,10 @@ BasicThebesLayerBuffer::DrawTo(ThebesLayer* aLayer,
|
|||
|
||||
// Pull out the mask surface and transform here, because the mask
|
||||
// is internal to basic layers
|
||||
gfxMatrix maskTransform;
|
||||
if (nsRefPtr<gfxASurface> maskSurface =
|
||||
GetMaskSurfaceAndTransform(aMaskLayer, &maskTransform)) {
|
||||
DrawBufferWithRotation(aTarget, aOpacity, maskSurface, &maskTransform);
|
||||
AutoMaskData mask;
|
||||
if (GetMaskData(aMaskLayer, &mask)) {
|
||||
DrawBufferWithRotation(aTarget, aOpacity,
|
||||
mask.GetSurface(), &mask.GetTransform());
|
||||
} else {
|
||||
DrawBufferWithRotation(aTarget, aOpacity);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,27 @@ public:
|
|||
gfxASurface* aSource, const nsIntRect& aRect, const nsIntPoint& aRotation,
|
||||
const nsIntRegion& aUpdateRegion);
|
||||
|
||||
/**
|
||||
* When BasicThebesLayerBuffer is used with layers that hold
|
||||
* SurfaceDescriptor, this buffer only has a valid gfxASurface in
|
||||
* the scope of an AutoOpenSurface for that SurfaceDescriptor. That
|
||||
* is, it's sort of a "virtual buffer" that's only mapped an
|
||||
* unmapped within the scope of AutoOpenSurface. None of the
|
||||
* underlying buffer attributes (rect, rotation) are affected by
|
||||
* mapping/unmapping.
|
||||
*
|
||||
* These helpers just exist to provide more descriptive names of the
|
||||
* map/unmap process.
|
||||
*/
|
||||
void MapBuffer(gfxASurface* aBuffer)
|
||||
{
|
||||
SetBuffer(aBuffer);
|
||||
}
|
||||
void UnmapBuffer()
|
||||
{
|
||||
SetBuffer(nsnull);
|
||||
}
|
||||
|
||||
private:
|
||||
BasicThebesLayerBuffer(gfxASurface* aBuffer,
|
||||
const nsIntRect& aRect, const nsIntPoint& aRotation)
|
||||
|
@ -87,18 +108,25 @@ public:
|
|||
MOZ_COUNT_DTOR(ShadowThebesLayerBuffer);
|
||||
}
|
||||
|
||||
void Swap(gfxASurface* aNewBuffer,
|
||||
const nsIntRect& aNewRect, const nsIntPoint& aNewRotation,
|
||||
gfxASurface** aOldBuffer,
|
||||
/**
|
||||
* Swap in the old "virtual buffer" (see above) attributes in aNew*
|
||||
* and return the old ones in aOld*.
|
||||
*
|
||||
* Swap() must only be called when the buffer is in its "unmapped"
|
||||
* state, that is the underlying gfxASurface is not available. It
|
||||
* is expected that the owner of this buffer holds an unmapped
|
||||
* SurfaceDescriptor as the backing storage for this buffer. That's
|
||||
* why no gfxASurface or SurfaceDescriptor parameters appear here.
|
||||
*/
|
||||
void Swap(const nsIntRect& aNewRect, const nsIntPoint& aNewRotation,
|
||||
nsIntRect* aOldRect, nsIntPoint* aOldRotation)
|
||||
{
|
||||
*aOldRect = BufferRect();
|
||||
*aOldRotation = BufferRotation();
|
||||
|
||||
nsRefPtr<gfxASurface> oldBuffer;
|
||||
oldBuffer = SetBuffer(aNewBuffer,
|
||||
aNewRect, aNewRotation);
|
||||
oldBuffer.forget(aOldBuffer);
|
||||
oldBuffer = SetBuffer(nsnull, aNewRect, aNewRotation);
|
||||
MOZ_ASSERT(!oldBuffer);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -113,4 +141,4 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -339,9 +339,8 @@ BasicShadowableCanvasLayer::Initialize(const Data& aData)
|
|||
// canvas resizes
|
||||
|
||||
if (IsSurfaceDescriptorValid(mBackBuffer)) {
|
||||
nsRefPtr<gfxASurface> backSurface =
|
||||
BasicManager()->OpenDescriptor(mBackBuffer);
|
||||
if (gfxIntSize(mBounds.width, mBounds.height) != backSurface->GetSize()) {
|
||||
AutoOpenSurface backSurface(OPEN_READ_ONLY, mBackBuffer);
|
||||
if (gfxIntSize(mBounds.width, mBounds.height) != backSurface.Size()) {
|
||||
DestroyBackBuffer();
|
||||
}
|
||||
}
|
||||
|
@ -368,15 +367,13 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
|||
NS_RUNTIMEABORT("creating CanvasLayer back buffer failed!");
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> backSurface =
|
||||
BasicManager()->OpenDescriptor(mBackBuffer);
|
||||
|
||||
AutoOpenSurface autoBackSurface(OPEN_READ_WRITE, mBackBuffer);
|
||||
|
||||
if (aMaskLayer) {
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())
|
||||
->Paint(aContext, nsnull);
|
||||
}
|
||||
UpdateSurface(backSurface, nsnull);
|
||||
UpdateSurface(autoBackSurface.Get(), nsnull);
|
||||
FireDidTransactionCallback();
|
||||
|
||||
BasicManager()->PaintedCanvas(BasicManager()->Hold(this),
|
||||
|
@ -437,15 +434,14 @@ void
|
|||
BasicShadowCanvasLayer::Swap(const CanvasSurface& aNewFront, bool needYFlip,
|
||||
CanvasSurface* aNewBack)
|
||||
{
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
BasicManager()->OpenDescriptor(aNewFront);
|
||||
AutoOpenSurface autoSurface(OPEN_READ_ONLY, aNewFront);
|
||||
// Destroy mFrontBuffer if size different
|
||||
gfxIntSize sz = surface->GetSize();
|
||||
gfxIntSize sz = autoSurface.Size();
|
||||
bool surfaceConfigChanged = sz != gfxIntSize(mBounds.width, mBounds.height);
|
||||
if (IsSurfaceDescriptorValid(mFrontSurface)) {
|
||||
nsRefPtr<gfxASurface> front = BasicManager()->OpenDescriptor(mFrontSurface);
|
||||
AutoOpenSurface autoFront(OPEN_READ_ONLY, mFrontSurface);
|
||||
surfaceConfigChanged = surfaceConfigChanged ||
|
||||
surface->GetContentType() != front->GetContentType();
|
||||
autoSurface.ContentType() != autoFront.ContentType();
|
||||
}
|
||||
if (surfaceConfigChanged) {
|
||||
DestroyFrontBuffer();
|
||||
|
@ -459,7 +455,7 @@ BasicShadowCanvasLayer::Swap(const CanvasSurface& aNewFront, bool needYFlip,
|
|||
} else {
|
||||
*aNewBack = null_t();
|
||||
}
|
||||
mFrontSurface = aNewFront.get_SurfaceDescriptor();
|
||||
mFrontSurface = aNewFront;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -472,9 +468,8 @@ BasicShadowCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
|||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
BasicManager()->OpenDescriptor(mFrontSurface);
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(surface);
|
||||
AutoOpenSurface autoSurface(OPEN_READ_ONLY, mFrontSurface);
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(autoSurface.Get());
|
||||
|
||||
pat->SetFilter(mFilter);
|
||||
pat->SetExtend(gfxPattern::EXTEND_PAD);
|
||||
|
|
|
@ -41,7 +41,8 @@ public:
|
|||
gfxContext* aContext,
|
||||
Layer* aMaskLayer);
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface();
|
||||
virtual bool GetAsSurface(gfxASurface** aSurface,
|
||||
SurfaceDescriptor* aDescriptor);
|
||||
|
||||
protected:
|
||||
BasicLayerManager* BasicManager()
|
||||
|
@ -86,9 +87,6 @@ BasicImageLayer::GetAndPaintCurrentImage(gfxContext* aContext,
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
NS_ASSERTION(surface->GetContentType() != gfxASurface::CONTENT_ALPHA,
|
||||
"Image layer has alpha image");
|
||||
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(surface);
|
||||
if (!pat) {
|
||||
return nsnull;
|
||||
|
@ -154,15 +152,18 @@ BasicImageLayer::PaintContext(gfxPattern* aPattern,
|
|||
aPattern->SetExtend(extend);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
BasicImageLayer::GetAsSurface()
|
||||
bool
|
||||
BasicImageLayer::GetAsSurface(gfxASurface** aSurface,
|
||||
SurfaceDescriptor* aDescriptor)
|
||||
{
|
||||
if (!mContainer) {
|
||||
return nsnull;
|
||||
return false;
|
||||
}
|
||||
|
||||
gfxIntSize dontCare;
|
||||
return mContainer->GetCurrentAsSurface(&dontCare);
|
||||
nsRefPtr<gfxASurface> surface = mContainer->GetCurrentAsSurface(&dontCare);
|
||||
*aSurface = surface.forget().get();
|
||||
return true;
|
||||
}
|
||||
|
||||
class BasicShadowableImageLayer : public BasicImageLayer,
|
||||
|
@ -295,8 +296,8 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
|||
}
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> dyas = BasicManager()->OpenDescriptor(mBackBufferY);
|
||||
nsRefPtr<gfxImageSurface> dy = dyas->GetAsImageSurface();
|
||||
AutoOpenSurface dyas(OPEN_READ_WRITE, mBackBufferY);
|
||||
gfxImageSurface* dy = dyas.GetAsImage();
|
||||
|
||||
for (int i = 0; i < data->mYSize.height; i++) {
|
||||
memcpy(dy->Data() + i * dy->Stride(),
|
||||
|
@ -304,10 +305,10 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
|||
data->mYSize.width);
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> duas = BasicManager()->OpenDescriptor(mBackBufferU);
|
||||
nsRefPtr<gfxImageSurface> du = duas->GetAsImageSurface();
|
||||
nsRefPtr<gfxASurface> dvas = BasicManager()->OpenDescriptor(mBackBufferV);
|
||||
nsRefPtr<gfxImageSurface> dv = dvas->GetAsImageSurface();
|
||||
AutoOpenSurface duas(OPEN_READ_WRITE, mBackBufferU);
|
||||
gfxImageSurface* du = duas.GetAsImage();
|
||||
AutoOpenSurface dvas(OPEN_READ_WRITE, mBackBufferV);
|
||||
gfxImageSurface* dv = dvas.GetAsImage();
|
||||
|
||||
for (int i = 0; i < data->mCbCrSize.height; i++) {
|
||||
memcpy(du->Data() + i * du->Stride(),
|
||||
|
@ -352,9 +353,8 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
|||
NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!");
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> backSurface =
|
||||
BasicManager()->OpenDescriptor(mBackBuffer);
|
||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(backSurface);
|
||||
AutoOpenSurface backSurface(OPEN_READ_WRITE, mBackBuffer);
|
||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(backSurface.Get());
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
PaintContext(pat,
|
||||
nsIntRegion(nsIntRect(0, 0, mSize.width, mSize.height)),
|
||||
|
@ -393,7 +393,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
already_AddRefed<gfxASurface> GetAsSurface();
|
||||
virtual bool GetAsSurface(gfxASurface** aSurface,
|
||||
SurfaceDescriptor* aDescriptor);
|
||||
|
||||
protected:
|
||||
BasicShadowLayerManager* BasicManager()
|
||||
|
@ -409,18 +410,17 @@ void
|
|||
BasicShadowImageLayer::Swap(const SharedImage& aNewFront,
|
||||
SharedImage* aNewBack)
|
||||
{
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
BasicManager()->OpenDescriptor(aNewFront);
|
||||
AutoOpenSurface autoSurface(OPEN_READ_ONLY, aNewFront);
|
||||
// Destroy mFrontBuffer if size different or image type is different
|
||||
bool surfaceConfigChanged = surface->GetSize() != mSize;
|
||||
bool surfaceConfigChanged = autoSurface.Size() != mSize;
|
||||
if (IsSurfaceDescriptorValid(mFrontBuffer)) {
|
||||
nsRefPtr<gfxASurface> front = BasicManager()->OpenDescriptor(mFrontBuffer);
|
||||
AutoOpenSurface autoFront(OPEN_READ_ONLY, mFrontBuffer);
|
||||
surfaceConfigChanged = surfaceConfigChanged ||
|
||||
surface->GetContentType() != front->GetContentType();
|
||||
autoSurface.ContentType() != autoFront.ContentType();
|
||||
}
|
||||
if (surfaceConfigChanged) {
|
||||
DestroyFrontBuffer();
|
||||
mSize = surface->GetSize();
|
||||
mSize = autoSurface.Size();
|
||||
}
|
||||
|
||||
// If mFrontBuffer
|
||||
|
@ -429,7 +429,7 @@ BasicShadowImageLayer::Swap(const SharedImage& aNewFront,
|
|||
} else {
|
||||
*aNewBack = null_t();
|
||||
}
|
||||
mFrontBuffer = aNewFront.get_SurfaceDescriptor();
|
||||
mFrontBuffer = aNewFront;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -439,9 +439,8 @@ BasicShadowImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
|||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
BasicManager()->OpenDescriptor(mFrontBuffer);
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(surface);
|
||||
AutoOpenSurface autoSurface(OPEN_READ_ONLY, mFrontBuffer);
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(autoSurface.Get());
|
||||
pat->SetFilter(mFilter);
|
||||
|
||||
// The visible region can extend outside the image, so just draw
|
||||
|
@ -453,14 +452,16 @@ BasicShadowImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
|||
aMaskLayer);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
BasicShadowImageLayer::GetAsSurface()
|
||||
bool
|
||||
BasicShadowImageLayer::GetAsSurface(gfxASurface** aSurface,
|
||||
SurfaceDescriptor* aDescriptor)
|
||||
{
|
||||
if (!IsSurfaceDescriptorValid(mFrontBuffer)) {
|
||||
return nsnull;
|
||||
return false;
|
||||
}
|
||||
|
||||
return BasicManager()->OpenDescriptor(mFrontBuffer);
|
||||
*aDescriptor = mFrontBuffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<ImageLayer>
|
||||
|
|
|
@ -101,11 +101,14 @@ public:
|
|||
|
||||
/**
|
||||
* Return a surface for this layer. Will use an existing surface, if
|
||||
* possible, or may create a temporary surface.
|
||||
* Implement this method for any layers that might be used as a mask.
|
||||
* Should only return null if a surface cannor be created.
|
||||
* possible, or may create a temporary surface. Implement this
|
||||
* method for any layers that might be used as a mask. Should only
|
||||
* return false if a surface cannot be created. If true is
|
||||
* returned, only one of |aSurface| or |aDescriptor| is valid.
|
||||
*/
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface() { return nsnull; }
|
||||
virtual bool GetAsSurface(gfxASurface** aSurface,
|
||||
SurfaceDescriptor* aDescriptor)
|
||||
{ return false; }
|
||||
|
||||
bool GetClipToVisibleRegion() { return mClipToVisibleRegion; }
|
||||
void SetClipToVisibleRegion(bool aClip) { mClipToVisibleRegion = aClip; }
|
||||
|
|
|
@ -4,41 +4,91 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BasicLayersImpl.h"
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
GetMaskSurfaceAndTransform(Layer* aMaskLayer, gfxMatrix* aMaskTransform)
|
||||
void
|
||||
AutoMaskData::Construct(const gfxMatrix& aTransform,
|
||||
gfxASurface* aSurface)
|
||||
{
|
||||
if (aMaskLayer) {
|
||||
nsRefPtr<gfxASurface> maskSurface =
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())->GetAsSurface();
|
||||
if (maskSurface) {
|
||||
bool maskIs2D =
|
||||
aMaskLayer->GetEffectiveTransform().CanDraw2D(aMaskTransform);
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
return maskSurface.forget();
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
MOZ_ASSERT(!IsConstructed());
|
||||
mTransform = aTransform;
|
||||
mSurface = aSurface;
|
||||
}
|
||||
|
||||
void
|
||||
AutoMaskData::Construct(const gfxMatrix& aTransform,
|
||||
const SurfaceDescriptor& aSurface)
|
||||
{
|
||||
MOZ_ASSERT(!IsConstructed());
|
||||
mTransform = aTransform;
|
||||
mSurfaceOpener.construct(OPEN_READ_ONLY, aSurface);
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
AutoMaskData::GetSurface()
|
||||
{
|
||||
MOZ_ASSERT(IsConstructed());
|
||||
if (mSurface) {
|
||||
return mSurface.get();
|
||||
}
|
||||
return mSurfaceOpener.ref().Get();
|
||||
}
|
||||
|
||||
const gfxMatrix&
|
||||
AutoMaskData::GetTransform()
|
||||
{
|
||||
MOZ_ASSERT(IsConstructed());
|
||||
return mTransform;
|
||||
}
|
||||
|
||||
bool
|
||||
AutoMaskData::IsConstructed()
|
||||
{
|
||||
return !!mSurface || !mSurfaceOpener.empty();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GetMaskData(Layer* aMaskLayer, AutoMaskData* aMaskData)
|
||||
{
|
||||
if (aMaskLayer) {
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
SurfaceDescriptor descriptor;
|
||||
if (static_cast<BasicImplData*>(aMaskLayer->ImplData())
|
||||
->GetAsSurface(getter_AddRefs(surface), &descriptor) &&
|
||||
(surface || IsSurfaceDescriptorValid(descriptor))) {
|
||||
gfxMatrix transform;
|
||||
DebugOnly<bool> maskIs2D =
|
||||
aMaskLayer->GetEffectiveTransform().CanDraw2D(&transform);
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
if (surface) {
|
||||
aMaskData->Construct(transform, surface);
|
||||
} else {
|
||||
aMaskData->Construct(transform, descriptor);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
|
||||
{
|
||||
gfxMatrix maskTransform;
|
||||
if (nsRefPtr<gfxASurface> maskSurface =
|
||||
GetMaskSurfaceAndTransform(aMaskLayer, &maskTransform)) {
|
||||
AutoMaskData mask;
|
||||
if (GetMaskData(aMaskLayer, &mask)) {
|
||||
if (aOpacity < 1.0) {
|
||||
aContext->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
aContext->Paint(aOpacity);
|
||||
aContext->PopGroupToSource();
|
||||
}
|
||||
aContext->SetMatrix(maskTransform);
|
||||
aContext->Mask(maskSurface);
|
||||
aContext->SetMatrix(mask.GetTransform());
|
||||
aContext->Mask(mask.GetSurface());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -49,20 +99,19 @@ PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
|
|||
void
|
||||
FillWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
|
||||
{
|
||||
gfxMatrix maskTransform;
|
||||
if (nsRefPtr<gfxASurface> maskSurface =
|
||||
GetMaskSurfaceAndTransform(aMaskLayer, &maskTransform)) {
|
||||
AutoMaskData mask;
|
||||
if (GetMaskData(aMaskLayer, &mask)) {
|
||||
if (aOpacity < 1.0) {
|
||||
aContext->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
aContext->FillWithOpacity(aOpacity);
|
||||
aContext->PopGroupToSource();
|
||||
aContext->SetMatrix(maskTransform);
|
||||
aContext->Mask(maskSurface);
|
||||
aContext->SetMatrix(mask.GetTransform());
|
||||
aContext->Mask(mask.GetSurface());
|
||||
} else {
|
||||
aContext->Save();
|
||||
aContext->Clip();
|
||||
aContext->SetMatrix(maskTransform);
|
||||
aContext->Mask(maskSurface);
|
||||
aContext->SetMatrix(mask.GetTransform());
|
||||
aContext->Mask(mask.GetSurface());
|
||||
aContext->NewPath();
|
||||
aContext->Restore();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef GFX_BASICLAYERSIMPL_H
|
||||
#define GFX_BASICLAYERSIMPL_H
|
||||
|
||||
#include "ipc/AutoOpenSurface.h"
|
||||
#include "ipc/ShadowLayerChild.h"
|
||||
#include "BasicLayers.h"
|
||||
#include "BasicImplData.h"
|
||||
|
@ -62,14 +63,58 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Drawing with a mask requires a mask surface and a transform.
|
||||
* Sometimes the mask surface is a direct gfxASurface, but other times
|
||||
* it's a SurfaceDescriptor. For SurfaceDescriptor, we need to use a
|
||||
* scoped AutoOpenSurface to get a gfxASurface for the
|
||||
* SurfaceDescriptor.
|
||||
*
|
||||
* This helper class manages the gfxASurface-or-SurfaceDescriptor
|
||||
* logic.
|
||||
*/
|
||||
class NS_STACK_CLASS AutoMaskData {
|
||||
public:
|
||||
AutoMaskData() { }
|
||||
~AutoMaskData() { }
|
||||
|
||||
/**
|
||||
* Construct this out of either a gfxASurface or a
|
||||
* SurfaceDescriptor. Construct() must only be called once.
|
||||
* GetSurface() and GetTransform() must not be called until this has
|
||||
* been constructed.
|
||||
*/
|
||||
|
||||
void Construct(const gfxMatrix& aTransform,
|
||||
gfxASurface* aSurface);
|
||||
|
||||
void Construct(const gfxMatrix& aTransform,
|
||||
const SurfaceDescriptor& aSurface);
|
||||
|
||||
/** The returned surface can't escape the scope of |this|. */
|
||||
gfxASurface* GetSurface();
|
||||
const gfxMatrix& GetTransform();
|
||||
|
||||
private:
|
||||
bool IsConstructed();
|
||||
|
||||
gfxMatrix mTransform;
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
Maybe<AutoOpenSurface> mSurfaceOpener;
|
||||
|
||||
AutoMaskData(const AutoMaskData&) MOZ_DELETE;
|
||||
AutoMaskData& operator=(const AutoMaskData&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
/*
|
||||
* Extract a mask surface for a mask layer
|
||||
* Returns a surface for the mask layer if a mask layer is present and has a
|
||||
* valid surface and transform; nsnull otherwise.
|
||||
* The transform for the layer will be put in aMaskTransform
|
||||
* Returns true and through outparams a surface for the mask layer if
|
||||
* a mask layer is present and has a valid surface and transform;
|
||||
* false otherwise.
|
||||
* The transform for the layer will be put in aMaskData
|
||||
*/
|
||||
already_AddRefed<gfxASurface>
|
||||
GetMaskSurfaceAndTransform(Layer* aMaskLayer, gfxMatrix* aMaskTransform);
|
||||
bool
|
||||
GetMaskData(Layer* aMaskLayer, AutoMaskData* aMaskData);
|
||||
|
||||
// Paint the current source to a context using a mask, if present
|
||||
void
|
||||
|
|
|
@ -228,6 +228,58 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AutoOpenBuffer is a helper that builds on top of AutoOpenSurface,
|
||||
* which we need to get a gfxASurface from a SurfaceDescriptor. For
|
||||
* other layer types, simple lexical scoping of AutoOpenSurface is
|
||||
* easy. For ThebesLayers, the lifetime of buffer mappings doesn't
|
||||
* exactly match simple lexical scopes, so naively putting
|
||||
* AutoOpenSurfaces on the stack doesn't always work. We use this
|
||||
* helper to track openings instead.
|
||||
*
|
||||
* Any surface that's opened while painting this ThebesLayer will
|
||||
* notify this helper and register itself for unmapping.
|
||||
*
|
||||
* We ignore buffer destruction here because the shadow layers
|
||||
* protocol already ensures that destroyed buffers stay alive until
|
||||
* end-of-transaction.
|
||||
*/
|
||||
struct NS_STACK_CLASS AutoBufferTracker {
|
||||
AutoBufferTracker(BasicShadowableThebesLayer* aLayer)
|
||||
: mLayer(aLayer)
|
||||
{
|
||||
MOZ_ASSERT(!mLayer->mBufferTracker);
|
||||
|
||||
mLayer->mBufferTracker = this;
|
||||
if (IsSurfaceDescriptorValid(mLayer->mBackBuffer)) {
|
||||
mInitialBuffer.construct(OPEN_READ_WRITE, mLayer->mBackBuffer);
|
||||
mLayer->mBuffer.MapBuffer(mInitialBuffer.ref().Get());
|
||||
}
|
||||
}
|
||||
|
||||
~AutoBufferTracker() {
|
||||
mLayer->mBufferTracker = nsnull;
|
||||
mLayer->mBuffer.UnmapBuffer();
|
||||
// mInitialBuffer and mNewBuffer will clean up after themselves if
|
||||
// they were constructed.
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
CreatedBuffer(const SurfaceDescriptor& aDescriptor) {
|
||||
Maybe<AutoOpenSurface>* surface = mNewBuffers.AppendElement();
|
||||
surface->construct(OPEN_READ_WRITE, aDescriptor);
|
||||
return surface->ref().Get();
|
||||
}
|
||||
|
||||
Maybe<AutoOpenSurface> mInitialBuffer;
|
||||
nsAutoTArray<Maybe<AutoOpenSurface>, 2> mNewBuffers;
|
||||
BasicShadowableThebesLayer* mLayer;
|
||||
|
||||
private:
|
||||
AutoBufferTracker(const AutoBufferTracker&) MOZ_DELETE;
|
||||
AutoBufferTracker& operator=(const AutoBufferTracker&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
void
|
||||
BasicShadowableThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
|
@ -240,6 +292,8 @@ BasicShadowableThebesLayer::PaintThebes(gfxContext* aContext,
|
|||
return;
|
||||
}
|
||||
|
||||
AutoBufferTracker tracker(this);
|
||||
|
||||
BasicThebesLayer::PaintThebes(aContext, nsnull, aCallback, aCallbackData, aReadback);
|
||||
if (aMaskLayer) {
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())
|
||||
|
@ -280,18 +334,22 @@ BasicShadowableThebesLayer::SyncFrontBufferToBackBuffer()
|
|||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> backBuffer;
|
||||
gfxASurface* backBuffer = mBuffer.GetBuffer();
|
||||
if (!IsSurfaceDescriptorValid(mBackBuffer)) {
|
||||
NS_ABORT_IF_FALSE(mROFrontBuffer.type() == OptionalThebesBuffer::TThebesBuffer,
|
||||
"should have a front RO buffer by now");
|
||||
MOZ_ASSERT(!backBuffer);
|
||||
MOZ_ASSERT(mROFrontBuffer.type() == OptionalThebesBuffer::TThebesBuffer);
|
||||
const ThebesBuffer roFront = mROFrontBuffer.get_ThebesBuffer();
|
||||
nsRefPtr<gfxASurface> roFrontBuffer = BasicManager()->OpenDescriptor(roFront.buffer());
|
||||
backBuffer = CreateBuffer(roFrontBuffer->GetContentType(), roFrontBuffer->GetSize());
|
||||
} else {
|
||||
backBuffer = BasicManager()->OpenDescriptor(mBackBuffer);
|
||||
AutoOpenSurface roFrontBuffer(OPEN_READ_ONLY, roFront.buffer());
|
||||
AllocBackBuffer(roFrontBuffer.ContentType(), roFrontBuffer.Size());
|
||||
}
|
||||
mFrontAndBackBufferDiffer = false;
|
||||
|
||||
Maybe<AutoOpenSurface> autoBackBuffer;
|
||||
if (!backBuffer) {
|
||||
autoBackBuffer.construct(OPEN_READ_WRITE, mBackBuffer);
|
||||
backBuffer = autoBackBuffer.ref().Get();
|
||||
}
|
||||
|
||||
if (OptionalThebesBuffer::Tnull_t == mROFrontBuffer.type()) {
|
||||
// We didn't get back a read-only ref to our old back buffer (the
|
||||
// parent's new front buffer). If the parent is pushing updates
|
||||
|
@ -310,10 +368,10 @@ BasicShadowableThebesLayer::SyncFrontBufferToBackBuffer()
|
|||
mFrontUpdatedRegion.GetBounds().height));
|
||||
|
||||
const ThebesBuffer roFront = mROFrontBuffer.get_ThebesBuffer();
|
||||
nsRefPtr<gfxASurface> roFrontBuffer = BasicManager()->OpenDescriptor(roFront.buffer());
|
||||
AutoOpenSurface autoROFront(OPEN_READ_ONLY, roFront.buffer());
|
||||
mBuffer.SetBackingBufferAndUpdateFrom(
|
||||
backBuffer,
|
||||
roFrontBuffer, roFront.rect(), roFront.rotation(),
|
||||
autoROFront.Get(), roFront.rect(), roFront.rotation(),
|
||||
mFrontUpdatedRegion);
|
||||
mIsNewBuffer = false;
|
||||
// Now the new back buffer has the same (interesting) pixels as the
|
||||
|
@ -364,6 +422,23 @@ BasicShadowableThebesLayer::PaintBuffer(gfxContext* aContext,
|
|||
mBackBuffer);
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowableThebesLayer::AllocBackBuffer(Buffer::ContentType aType,
|
||||
const nsIntSize& aSize)
|
||||
{
|
||||
// This function may *not* open the buffer it allocates.
|
||||
if (!BasicManager()->AllocBuffer(gfxIntSize(aSize.width, aSize.height),
|
||||
aType,
|
||||
&mBackBuffer)) {
|
||||
enum { buflen = 256 };
|
||||
char buf[buflen];
|
||||
PR_snprintf(buf, buflen,
|
||||
"creating ThebesLayer 'back buffer' failed! width=%d, height=%d, type=%x",
|
||||
aSize.width, aSize.height, int(aType));
|
||||
NS_RUNTIMEABORT(buf);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
BasicShadowableThebesLayer::CreateBuffer(Buffer::ContentType aType,
|
||||
const nsIntSize& aSize)
|
||||
|
@ -382,24 +457,15 @@ BasicShadowableThebesLayer::CreateBuffer(Buffer::ContentType aType,
|
|||
mBackBuffer = SurfaceDescriptor();
|
||||
}
|
||||
|
||||
// XXX error handling
|
||||
if (!BasicManager()->AllocBuffer(gfxIntSize(aSize.width, aSize.height),
|
||||
aType,
|
||||
&mBackBuffer)) {
|
||||
enum { buflen = 256 };
|
||||
char buf[buflen];
|
||||
PR_snprintf(buf, buflen,
|
||||
"creating ThebesLayer 'back buffer' failed! width=%d, height=%d, type=%x",
|
||||
aSize.width, aSize.height, int(aType));
|
||||
NS_RUNTIMEABORT(buf);
|
||||
}
|
||||
AllocBackBuffer(aType, aSize);
|
||||
|
||||
NS_ABORT_IF_FALSE(!mIsNewBuffer,
|
||||
"Bad! Did we create a buffer twice without painting?");
|
||||
|
||||
mIsNewBuffer = true;
|
||||
|
||||
return BasicManager()->OpenDescriptor(mBackBuffer);
|
||||
nsRefPtr<gfxASurface> buffer = mBufferTracker->CreatedBuffer(mBackBuffer);
|
||||
return buffer.forget();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -483,12 +549,10 @@ BasicShadowThebesLayer::Swap(const ThebesBuffer& aNewFront,
|
|||
OptionalThebesBuffer* aReadOnlyFront,
|
||||
nsIntRegion* aFrontUpdatedRegion)
|
||||
{
|
||||
nsRefPtr<gfxASurface> newFrontBuffer =
|
||||
BasicManager()->OpenDescriptor(aNewFront.buffer());
|
||||
|
||||
if (IsSurfaceDescriptorValid(mFrontBufferDescriptor)) {
|
||||
nsRefPtr<gfxASurface> currentFront = BasicManager()->OpenDescriptor(mFrontBufferDescriptor);
|
||||
if (currentFront->GetSize() != newFrontBuffer->GetSize()) {
|
||||
AutoOpenSurface autoNewFrontBuffer(OPEN_READ_ONLY, aNewFront.buffer());
|
||||
AutoOpenSurface autoCurrentFront(OPEN_READ_ONLY, mFrontBufferDescriptor);
|
||||
if (autoCurrentFront.Size() != autoNewFrontBuffer.Size()) {
|
||||
// Current front buffer is obsolete
|
||||
DestroyFrontBuffer();
|
||||
}
|
||||
|
@ -504,12 +568,11 @@ BasicShadowThebesLayer::Swap(const ThebesBuffer& aNewFront,
|
|||
// They might overlap with our old pixels.
|
||||
aNewBackValidRegion->Sub(mOldValidRegion, aUpdatedRegion);
|
||||
|
||||
nsRefPtr<gfxASurface> unused;
|
||||
nsIntRect backRect;
|
||||
nsIntPoint backRotation;
|
||||
mFrontBuffer.Swap(
|
||||
newFrontBuffer, aNewFront.rect(), aNewFront.rotation(),
|
||||
getter_AddRefs(unused), &backRect, &backRotation);
|
||||
aNewFront.rect(), aNewFront.rotation(),
|
||||
&backRect, &backRotation);
|
||||
|
||||
if (aNewBack->type() != OptionalThebesBuffer::Tnull_t) {
|
||||
aNewBack->get_ThebesBuffer().rect() = backRect;
|
||||
|
@ -534,11 +597,16 @@ BasicShadowThebesLayer::PaintThebes(gfxContext* aContext,
|
|||
NS_ASSERTION(BasicManager()->IsRetained(),
|
||||
"ShadowThebesLayer makes no sense without retained mode");
|
||||
|
||||
if (!mFrontBuffer.GetBuffer()) {
|
||||
if (!IsSurfaceDescriptorValid(mFrontBufferDescriptor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoOpenSurface autoFrontBuffer(OPEN_READ_ONLY, mFrontBufferDescriptor);
|
||||
mFrontBuffer.MapBuffer(autoFrontBuffer.Get());
|
||||
|
||||
mFrontBuffer.DrawTo(this, aContext, GetEffectiveOpacity(), aMaskLayer);
|
||||
|
||||
mFrontBuffer.UnmapBuffer();
|
||||
}
|
||||
|
||||
already_AddRefed<ThebesLayer>
|
||||
|
|
|
@ -103,14 +103,19 @@ protected:
|
|||
Buffer mBuffer;
|
||||
};
|
||||
|
||||
struct AutoBufferTracker;
|
||||
|
||||
class BasicShadowableThebesLayer : public BasicThebesLayer,
|
||||
public BasicShadowableLayer
|
||||
{
|
||||
friend struct AutoBufferTracker;
|
||||
|
||||
typedef BasicThebesLayer Base;
|
||||
|
||||
public:
|
||||
BasicShadowableThebesLayer(BasicShadowLayerManager* aManager)
|
||||
: BasicThebesLayer(aManager)
|
||||
, mBufferTracker(nsnull)
|
||||
, mIsNewBuffer(false)
|
||||
, mFrontAndBackBufferDiffer(false)
|
||||
{
|
||||
|
@ -163,6 +168,10 @@ private:
|
|||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData) MOZ_OVERRIDE;
|
||||
|
||||
// This function may *not* open the buffer it allocates.
|
||||
void
|
||||
AllocBackBuffer(Buffer::ContentType aType, const nsIntSize& aSize);
|
||||
|
||||
virtual already_AddRefed<gfxASurface>
|
||||
CreateBuffer(Buffer::ContentType aType, const nsIntSize& aSize) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -180,6 +189,12 @@ private:
|
|||
nsIntRect mBackBufferRect;
|
||||
nsIntPoint mBackBufferRectRotation;
|
||||
|
||||
// This helper object lives on the stack during its lifetime and
|
||||
// keeps track of buffers we might have mapped and/or allocated.
|
||||
// When it goes out of scope on the stack, it unmaps whichever
|
||||
// buffers have been mapped (if any).
|
||||
AutoBufferTracker* mBufferTracker;
|
||||
|
||||
bool mIsNewBuffer;
|
||||
OptionalThebesBuffer mROFrontBuffer;
|
||||
nsIntRegion mFrontUpdatedRegion;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
#include "ipc/AutoOpenSurface.h"
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "ShadowBufferD3D9.h"
|
||||
|
@ -311,12 +312,11 @@ ShadowCanvasLayerD3D9::Swap(const CanvasSurface& aNewFront,
|
|||
NS_ASSERTION(aNewFront.type() == CanvasSurface::TSurfaceDescriptor,
|
||||
"ShadowCanvasLayerD3D9::Swap expected CanvasSurface surface");
|
||||
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
ShadowLayerForwarder::OpenDescriptor(aNewFront);
|
||||
AutoOpenSurface surf(OPEN_READ_ONLY, aNewFront);
|
||||
if (!mBuffer) {
|
||||
Init(needYFlip);
|
||||
}
|
||||
mBuffer->Upload(surf, GetVisibleRegion().GetBounds());
|
||||
mBuffer->Upload(surf.Get(), GetVisibleRegion().GetBounds());
|
||||
|
||||
*aNewBack = aNewFront;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ipc/AutoOpenSurface.h"
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "ShadowBufferD3D9.h"
|
||||
|
@ -551,22 +552,17 @@ ShadowImageLayerD3D9::Swap(const SharedImage& aNewFront,
|
|||
if (!mBuffer) {
|
||||
mBuffer = new ShadowBufferD3D9(this);
|
||||
}
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
ShadowLayerForwarder::OpenDescriptor(aNewFront.get_SurfaceDescriptor());
|
||||
|
||||
mBuffer->Upload(surf, GetVisibleRegion().GetBounds());
|
||||
AutoOpenSurface surf(OPEN_READ_ONLY, aNewFront.get_SurfaceDescriptor());
|
||||
mBuffer->Upload(surf.Get(), GetVisibleRegion().GetBounds());
|
||||
} else {
|
||||
const YUVImage& yuv = aNewFront.get_YUVImage();
|
||||
|
||||
nsRefPtr<gfxASurface> asurfY =
|
||||
ShadowLayerForwarder::OpenDescriptor(yuv.Ydata());
|
||||
nsRefPtr<gfxImageSurface> surfY = asurfY->GetAsImageSurface();
|
||||
nsRefPtr<gfxASurface> asurfU =
|
||||
ShadowLayerForwarder::OpenDescriptor(yuv.Udata());
|
||||
nsRefPtr<gfxImageSurface> surfU = asurfU->GetAsImageSurface();
|
||||
nsRefPtr<gfxASurface> asurfV =
|
||||
ShadowLayerForwarder::OpenDescriptor(yuv.Vdata());
|
||||
nsRefPtr<gfxImageSurface> surfV = asurfV->GetAsImageSurface();
|
||||
AutoOpenSurface asurfY(OPEN_READ_ONLY, yuv.Ydata());
|
||||
AutoOpenSurface asurfU(OPEN_READ_ONLY, yuv.Udata());
|
||||
AutoOpenSurface asurfV(OPEN_READ_ONLY, yuv.Vdata());
|
||||
gfxImageSurface* surfY = asurfY.GetAsImage();
|
||||
gfxImageSurface* surfU = asurfU.GetAsImage();
|
||||
gfxImageSurface* surfV = asurfV.GetAsImage();
|
||||
|
||||
PlanarYCbCrImage::Data data;
|
||||
data.mYChannel = surfY->Data();
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
/* This must occur *after* layers/PLayers.h to avoid typedefs conflicts. */
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include "ipc/AutoOpenSurface.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "ShadowBufferD3D9.h"
|
||||
|
||||
|
@ -617,8 +618,8 @@ ShadowThebesLayerD3D9::Swap(const ThebesBuffer& aNewFront,
|
|||
}
|
||||
|
||||
if (mBuffer) {
|
||||
nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront.buffer());
|
||||
mBuffer->Upload(surf, GetVisibleRegion().GetBounds());
|
||||
AutoOpenSurface surf(OPEN_READ_ONLY, aNewFront.buffer());
|
||||
mBuffer->Upload(surf.Get(), GetVisibleRegion().GetBounds());
|
||||
}
|
||||
|
||||
*aNewBack = aNewFront;
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_layers_AutoOpenSurface_h
|
||||
#define mozilla_layers_AutoOpenSurface_h 1
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#include "gfxASurface.h"
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
#include "ShadowLayers.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* Some surface types can be fairly expensive to open. This helper
|
||||
* tries to put off opening surfaces as long as it can, until
|
||||
* ahsolutely necessary. And after being forced to open, it remembers
|
||||
* the mapping so it doesn't need to be redone.
|
||||
*/
|
||||
class NS_STACK_CLASS AutoOpenSurface
|
||||
{
|
||||
public:
|
||||
typedef gfxASurface::gfxContentType gfxContentType;
|
||||
|
||||
/** |aDescriptor| must be valid while AutoOpenSurface is
|
||||
* in scope. */
|
||||
AutoOpenSurface(OpenMode aMode, const SurfaceDescriptor& aDescriptor);
|
||||
|
||||
~AutoOpenSurface();
|
||||
|
||||
/**
|
||||
* These helpers do not necessarily need to open the descriptor to
|
||||
* return an answer.
|
||||
*/
|
||||
gfxContentType ContentType();
|
||||
gfxIntSize Size();
|
||||
|
||||
/** This can't escape the scope of AutoOpenSurface. */
|
||||
gfxASurface* Get();
|
||||
|
||||
/**
|
||||
* This can't escape the scope of AutoOpenSurface.
|
||||
*
|
||||
* This method is currently just a convenience wrapper around
|
||||
* gfxASurface::GetAsImageSurface() --- it returns a valid surface
|
||||
* exactly when this->Get()->GetAsImageSurface() would. Clients
|
||||
* that need guaranteed (fast) ImageSurfaces should allocate the
|
||||
* underlying descriptor with capability MAP_AS_IMAGE_SURFACE, in
|
||||
* which case this helper is guaranteed to succeed.
|
||||
*/
|
||||
gfxImageSurface* GetAsImage();
|
||||
|
||||
|
||||
private:
|
||||
SurfaceDescriptor mDescriptor;
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
nsRefPtr<gfxImageSurface> mSurfaceAsImage;
|
||||
OpenMode mMode;
|
||||
|
||||
AutoOpenSurface(const AutoOpenSurface&) MOZ_DELETE;
|
||||
AutoOpenSurface& operator=(const AutoOpenSurface&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // ifndef mozilla_layers_AutoOpenSurface_h
|
|
@ -26,11 +26,38 @@ ShadowLayerForwarder::PlatformAllocBuffer(const gfxIntSize&,
|
|||
}
|
||||
|
||||
/*static*/ already_AddRefed<gfxASurface>
|
||||
ShadowLayerForwarder::PlatformOpenDescriptor(const SurfaceDescriptor&)
|
||||
ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode,
|
||||
const SurfaceDescriptor&)
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
ShadowLayerForwarder::PlatformGetDescriptorSurfaceContentType(
|
||||
const SurfaceDescriptor&,
|
||||
OpenMode,
|
||||
gfxContentType*,
|
||||
gfxASurface**)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
ShadowLayerForwarder::PlatformGetDescriptorSurfaceSize(
|
||||
const SurfaceDescriptor&,
|
||||
OpenMode,
|
||||
gfxIntSize*,
|
||||
gfxASurface**)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor*)
|
||||
{
|
||||
|
|
|
@ -123,7 +123,8 @@ ShadowLayerForwarder::PlatformAllocBuffer(const gfxIntSize& aSize,
|
|||
}
|
||||
|
||||
/*static*/ already_AddRefed<gfxASurface>
|
||||
ShadowLayerForwarder::PlatformOpenDescriptor(const SurfaceDescriptor& aSurface)
|
||||
ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode aMode,
|
||||
const SurfaceDescriptor& aSurface)
|
||||
{
|
||||
if (SurfaceDescriptor::TSurfaceDescriptorX11 != aSurface.type()) {
|
||||
return nsnull;
|
||||
|
@ -131,6 +132,31 @@ ShadowLayerForwarder::PlatformOpenDescriptor(const SurfaceDescriptor& aSurface)
|
|||
return aSurface.get_SurfaceDescriptorX11().OpenForeign();
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor& aDescriptor)
|
||||
{
|
||||
// XIDs don't need to be "closed".
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
ShadowLayerForwarder::PlatformGetDescriptorSurfaceContentType(
|
||||
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
|
||||
gfxContentType* aContent,
|
||||
gfxASurface** aSurface)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
ShadowLayerForwarder::PlatformGetDescriptorSurfaceSize(
|
||||
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
|
||||
gfxIntSize* aSize,
|
||||
gfxASurface** aSurface)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface)
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "gfxSharedImageSurface.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
#include "AutoOpenSurface.h"
|
||||
#include "mozilla/ipc/SharedMemorySysV.h"
|
||||
#include "mozilla/layers/PLayerChild.h"
|
||||
#include "mozilla/layers/PLayersChild.h"
|
||||
|
@ -355,7 +356,7 @@ ShadowLayerForwarder::ShadowDrawToTarget(gfxContext* aTarget) {
|
|||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface = OpenDescriptor(descriptorOut);
|
||||
nsRefPtr<gfxASurface> surface = OpenDescriptor(OPEN_READ_WRITE, descriptorOut);
|
||||
aTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
aTarget->DrawSurface(surface, surface->GetSize());
|
||||
|
||||
|
@ -434,9 +435,10 @@ ShadowLayerForwarder::AllocBufferWithCaps(const gfxIntSize& aSize,
|
|||
}
|
||||
|
||||
/*static*/ already_AddRefed<gfxASurface>
|
||||
ShadowLayerForwarder::OpenDescriptor(const SurfaceDescriptor& aSurface)
|
||||
ShadowLayerForwarder::OpenDescriptor(OpenMode aMode,
|
||||
const SurfaceDescriptor& aSurface)
|
||||
{
|
||||
nsRefPtr<gfxASurface> surf = PlatformOpenDescriptor(aSurface);
|
||||
nsRefPtr<gfxASurface> surf = PlatformOpenDescriptor(aMode, aSurface);
|
||||
if (surf) {
|
||||
return surf.forget();
|
||||
}
|
||||
|
@ -452,6 +454,46 @@ ShadowLayerForwarder::OpenDescriptor(const SurfaceDescriptor& aSurface)
|
|||
}
|
||||
}
|
||||
|
||||
/*static*/ gfxContentType
|
||||
ShadowLayerForwarder::GetDescriptorSurfaceContentType(
|
||||
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
|
||||
gfxASurface** aSurface)
|
||||
{
|
||||
gfxContentType content;
|
||||
if (PlatformGetDescriptorSurfaceContentType(aDescriptor, aMode,
|
||||
&content, aSurface)) {
|
||||
return content;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface = OpenDescriptor(aMode, aDescriptor);
|
||||
content = surface->GetContentType();
|
||||
*aSurface = surface.forget().get();
|
||||
return content;
|
||||
}
|
||||
|
||||
/*static*/ gfxIntSize
|
||||
ShadowLayerForwarder::GetDescriptorSurfaceSize(
|
||||
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
|
||||
gfxASurface** aSurface)
|
||||
{
|
||||
gfxIntSize size;
|
||||
if (PlatformGetDescriptorSurfaceSize(aDescriptor, aMode, &size, aSurface)) {
|
||||
return size;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface = OpenDescriptor(aMode, aDescriptor);
|
||||
size = surface->GetSize();
|
||||
*aSurface = surface.forget().get();
|
||||
return size;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
ShadowLayerForwarder::CloseDescriptor(const SurfaceDescriptor& aDescriptor)
|
||||
{
|
||||
PlatformCloseDescriptor(aDescriptor);
|
||||
// There's no "close" needed for Shmem surfaces.
|
||||
}
|
||||
|
||||
// Destroy the Shmem SurfaceDescriptor |aSurface|.
|
||||
template<class ShmemDeallocator>
|
||||
static void
|
||||
|
@ -522,11 +564,38 @@ ShadowLayerForwarder::PlatformAllocBuffer(const gfxIntSize&,
|
|||
}
|
||||
|
||||
/*static*/ already_AddRefed<gfxASurface>
|
||||
ShadowLayerForwarder::PlatformOpenDescriptor(const SurfaceDescriptor&)
|
||||
ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode,
|
||||
const SurfaceDescriptor&)
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
ShadowLayerForwarder::PlatformGetDescriptorSurfaceContentType(
|
||||
const SurfaceDescriptor&,
|
||||
OpenMode,
|
||||
gfxContentType*,
|
||||
gfxASurface**)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
ShadowLayerForwarder::PlatformGetDescriptorSurfaceSize(
|
||||
const SurfaceDescriptor&,
|
||||
OpenMode,
|
||||
gfxIntSize*,
|
||||
gfxASurface**)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor*)
|
||||
{
|
||||
|
@ -557,5 +626,60 @@ IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface)
|
|||
return SurfaceDescriptor::T__None != aSurface.type();
|
||||
}
|
||||
|
||||
AutoOpenSurface::AutoOpenSurface(OpenMode aMode,
|
||||
const SurfaceDescriptor& aDescriptor)
|
||||
: mDescriptor(aDescriptor)
|
||||
, mMode(aMode)
|
||||
{
|
||||
MOZ_ASSERT(IsSurfaceDescriptorValid(mDescriptor));
|
||||
}
|
||||
|
||||
AutoOpenSurface::~AutoOpenSurface()
|
||||
{
|
||||
if (mSurface) {
|
||||
mSurface = nsnull;
|
||||
ShadowLayerForwarder::CloseDescriptor(mDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
gfxContentType
|
||||
AutoOpenSurface::ContentType()
|
||||
{
|
||||
if (mSurface) {
|
||||
return mSurface->GetContentType();
|
||||
}
|
||||
return ShadowLayerForwarder::GetDescriptorSurfaceContentType(
|
||||
mDescriptor, mMode, getter_AddRefs(mSurface));
|
||||
}
|
||||
|
||||
gfxIntSize
|
||||
AutoOpenSurface::Size()
|
||||
{
|
||||
if (mSurface) {
|
||||
return mSurface->GetSize();
|
||||
}
|
||||
return ShadowLayerForwarder::GetDescriptorSurfaceSize(
|
||||
mDescriptor, mMode, getter_AddRefs(mSurface));
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
AutoOpenSurface::Get()
|
||||
{
|
||||
if (!mSurface) {
|
||||
mSurface = ShadowLayerForwarder::OpenDescriptor(mMode, mDescriptor);
|
||||
}
|
||||
return mSurface.get();
|
||||
}
|
||||
|
||||
gfxImageSurface*
|
||||
AutoOpenSurface::GetAsImage()
|
||||
{
|
||||
if (!mSurfaceAsImage) {
|
||||
mSurfaceAsImage = Get()->GetAsImageSurface();
|
||||
}
|
||||
return mSurfaceAsImage.get();
|
||||
}
|
||||
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -47,6 +47,11 @@ enum BufferCapabilities {
|
|||
MAP_AS_IMAGE_SURFACE = 1 << 0
|
||||
};
|
||||
|
||||
enum OpenMode {
|
||||
OPEN_READ_ONLY,
|
||||
OPEN_READ_WRITE
|
||||
};
|
||||
|
||||
/**
|
||||
* We want to share layer trees across thread contexts and address
|
||||
* spaces for several reasons; chief among them
|
||||
|
@ -90,7 +95,10 @@ enum BufferCapabilities {
|
|||
|
||||
class ShadowLayerForwarder
|
||||
{
|
||||
friend class AutoOpenSurface;
|
||||
|
||||
public:
|
||||
typedef gfxASurface::gfxContentType gfxContentType;
|
||||
typedef LayerManager::LayersBackend LayersBackend;
|
||||
|
||||
virtual ~ShadowLayerForwarder();
|
||||
|
@ -276,9 +284,6 @@ public:
|
|||
uint32_t aCaps,
|
||||
SurfaceDescriptor* aBuffer);
|
||||
|
||||
static already_AddRefed<gfxASurface>
|
||||
OpenDescriptor(const SurfaceDescriptor& aSurface);
|
||||
|
||||
void DestroySharedSurface(SurfaceDescriptor* aSurface);
|
||||
|
||||
/**
|
||||
|
@ -315,8 +320,48 @@ private:
|
|||
uint32_t aCaps,
|
||||
SurfaceDescriptor* aBuffer);
|
||||
|
||||
/**
|
||||
* Try to query the content type efficiently, but at worst map the
|
||||
* surface and return it in *aSurface.
|
||||
*/
|
||||
static gfxContentType
|
||||
GetDescriptorSurfaceContentType(const SurfaceDescriptor& aDescriptor,
|
||||
OpenMode aMode,
|
||||
gfxASurface** aSurface);
|
||||
/**
|
||||
* It can be expensive to open a descriptor just to query its
|
||||
* content type. If the platform impl can do this cheaply, it will
|
||||
* set *aContent and return true.
|
||||
*/
|
||||
static bool
|
||||
PlatformGetDescriptorSurfaceContentType(const SurfaceDescriptor& aDescriptor,
|
||||
OpenMode aMode,
|
||||
gfxContentType* aContent,
|
||||
gfxASurface** aSurface);
|
||||
// (Same as above, but for surface size.)
|
||||
static gfxIntSize
|
||||
GetDescriptorSurfaceSize(const SurfaceDescriptor& aDescriptor,
|
||||
OpenMode aMode,
|
||||
gfxASurface** aSurface);
|
||||
static bool
|
||||
PlatformGetDescriptorSurfaceSize(const SurfaceDescriptor& aDescriptor,
|
||||
OpenMode aMode,
|
||||
gfxIntSize* aSize,
|
||||
gfxASurface** aSurface);
|
||||
|
||||
static already_AddRefed<gfxASurface>
|
||||
PlatformOpenDescriptor(const SurfaceDescriptor& aDescriptor);
|
||||
OpenDescriptor(OpenMode aMode, const SurfaceDescriptor& aSurface);
|
||||
|
||||
static already_AddRefed<gfxASurface>
|
||||
PlatformOpenDescriptor(OpenMode aMode, const SurfaceDescriptor& aDescriptor);
|
||||
|
||||
/** Make this descriptor unusable for gfxASurface clients. A
|
||||
* private interface with AutoOpenSurface. */
|
||||
static void
|
||||
CloseDescriptor(const SurfaceDescriptor& aDescriptor);
|
||||
|
||||
static bool
|
||||
PlatformCloseDescriptor(const SurfaceDescriptor& aDescriptor);
|
||||
|
||||
bool PlatformDestroySharedSurface(SurfaceDescriptor* aSurface);
|
||||
|
||||
|
@ -329,7 +374,6 @@ private:
|
|||
bool mIsFirstPaint;
|
||||
};
|
||||
|
||||
|
||||
class ShadowLayerManager : public LayerManager
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "AutoOpenSurface.h"
|
||||
#include "ShadowLayersParent.h"
|
||||
#include "ShadowLayerParent.h"
|
||||
#include "ShadowLayers.h"
|
||||
|
@ -420,16 +421,16 @@ ShadowLayersParent::RecvDrawToSurface(const SurfaceDescriptor& surfaceIn,
|
|||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> sharedSurface = ShadowLayerForwarder::OpenDescriptor(surfaceIn);
|
||||
AutoOpenSurface sharedSurface(OPEN_READ_WRITE, surfaceIn);
|
||||
|
||||
nsRefPtr<gfxASurface> localSurface =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(sharedSurface->GetSize(),
|
||||
sharedSurface->GetContentType());
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(sharedSurface.Size(),
|
||||
sharedSurface.ContentType());
|
||||
nsRefPtr<gfxContext> context = new gfxContext(localSurface);
|
||||
|
||||
layer_manager()->BeginTransactionWithTarget(context);
|
||||
layer_manager()->EndTransaction(NULL, NULL);
|
||||
nsRefPtr<gfxContext> contextForCopy = new gfxContext(sharedSurface);
|
||||
nsRefPtr<gfxContext> contextForCopy = new gfxContext(sharedSurface.Get());
|
||||
contextForCopy->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
contextForCopy->DrawSurface(localSurface, localSurface->GetSize());
|
||||
return true;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ipc/AutoOpenSurface.h"
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
|
||||
|
@ -305,12 +306,12 @@ ShadowCanvasLayerOGL::Initialize(const Data& aData)
|
|||
void
|
||||
ShadowCanvasLayerOGL::Init(const CanvasSurface& aNewFront, bool needYFlip)
|
||||
{
|
||||
nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront);
|
||||
AutoOpenSurface autoSurf(OPEN_READ_ONLY, aNewFront);
|
||||
|
||||
mNeedsYFlip = needYFlip;
|
||||
|
||||
mTexImage = gl()->CreateTextureImage(surf->GetSize(),
|
||||
surf->GetContentType(),
|
||||
mTexImage = gl()->CreateTextureImage(autoSurf.Size(),
|
||||
autoSurf.ContentType(),
|
||||
LOCAL_GL_CLAMP_TO_EDGE,
|
||||
mNeedsYFlip ? TextureImage::NeedsYFlip : TextureImage::NoFlags);
|
||||
}
|
||||
|
@ -321,14 +322,14 @@ ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront,
|
|||
CanvasSurface* aNewBack)
|
||||
{
|
||||
if (!mDestroyed) {
|
||||
nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront);
|
||||
gfxIntSize sz = surf->GetSize();
|
||||
AutoOpenSurface autoSurf(OPEN_READ_ONLY, aNewFront);
|
||||
gfxIntSize sz = autoSurf.Size();
|
||||
if (!mTexImage || mTexImage->GetSize() != sz ||
|
||||
mTexImage->GetContentType() != surf->GetContentType()) {
|
||||
mTexImage->GetContentType() != autoSurf.ContentType()) {
|
||||
Init(aNewFront, needYFlip);
|
||||
}
|
||||
nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height));
|
||||
mTexImage->DirectUpdate(surf, updateRegion);
|
||||
mTexImage->DirectUpdate(autoSurf.Get(), updateRegion);
|
||||
}
|
||||
|
||||
*aNewBack = aNewFront;
|
||||
|
@ -365,6 +366,10 @@ void
|
|||
ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
||||
const nsIntPoint& aOffset)
|
||||
{
|
||||
if (!mTexImage) {
|
||||
return;
|
||||
}
|
||||
|
||||
mOGLManager->MakeCurrent();
|
||||
|
||||
ShaderProgramOGL *program =
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "gfxSharedImageSurface.h"
|
||||
|
||||
#include "ipc/AutoOpenSurface.h"
|
||||
#include "ImageLayerOGL.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxUtils.h"
|
||||
|
@ -660,12 +661,10 @@ bool
|
|||
ShadowImageLayerOGL::Init(const SharedImage& aFront)
|
||||
{
|
||||
if (aFront.type() == SharedImage::TSurfaceDescriptor) {
|
||||
SurfaceDescriptor desc = aFront.get_SurfaceDescriptor();
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
ShadowLayerForwarder::OpenDescriptor(desc);
|
||||
mSize = surf->GetSize();
|
||||
AutoOpenSurface autoSurf(OPEN_READ_ONLY, aFront.get_SurfaceDescriptor());
|
||||
mSize = autoSurf.Size();
|
||||
mTexImage = gl()->CreateTextureImage(nsIntSize(mSize.width, mSize.height),
|
||||
surf->GetContentType(),
|
||||
autoSurf.ContentType(),
|
||||
LOCAL_GL_CLAMP_TO_EDGE,
|
||||
mForceSingleTile
|
||||
? TextureImage::ForceSingleTile
|
||||
|
@ -674,15 +673,11 @@ ShadowImageLayerOGL::Init(const SharedImage& aFront)
|
|||
} else {
|
||||
YUVImage yuv = aFront.get_YUVImage();
|
||||
|
||||
nsRefPtr<gfxASurface> asurfY =
|
||||
ShadowLayerForwarder::OpenDescriptor(yuv.Ydata());
|
||||
nsRefPtr<gfxImageSurface> surfY = asurfY->GetAsImageSurface();
|
||||
nsRefPtr<gfxASurface> asurfU =
|
||||
ShadowLayerForwarder::OpenDescriptor(yuv.Udata());
|
||||
nsRefPtr<gfxImageSurface> surfU = asurfU->GetAsImageSurface();
|
||||
AutoOpenSurface surfY(OPEN_READ_ONLY, yuv.Ydata());
|
||||
AutoOpenSurface surfU(OPEN_READ_ONLY, yuv.Udata());
|
||||
|
||||
mSize = surfY->GetSize();
|
||||
mCbCrSize = surfU->GetSize();
|
||||
mSize = surfY.Size();
|
||||
mCbCrSize = surfU.Size();
|
||||
|
||||
if (!mYUVTexture[0].IsAllocated()) {
|
||||
mYUVTexture[0].Allocate(gl());
|
||||
|
@ -710,29 +705,24 @@ ShadowImageLayerOGL::Swap(const SharedImage& aNewFront,
|
|||
{
|
||||
if (!mDestroyed) {
|
||||
if (aNewFront.type() == SharedImage::TSurfaceDescriptor) {
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
ShadowLayerForwarder::OpenDescriptor(aNewFront.get_SurfaceDescriptor());
|
||||
gfxIntSize size = surf->GetSize();
|
||||
AutoOpenSurface surf(OPEN_READ_ONLY, aNewFront.get_SurfaceDescriptor());
|
||||
gfxIntSize size = surf.Size();
|
||||
if (mSize != size || !mTexImage ||
|
||||
mTexImage->GetContentType() != surf->GetContentType()) {
|
||||
mTexImage->GetContentType() != surf.ContentType()) {
|
||||
Init(aNewFront);
|
||||
}
|
||||
// XXX this is always just ridiculously slow
|
||||
nsIntRegion updateRegion(nsIntRect(0, 0, size.width, size.height));
|
||||
mTexImage->DirectUpdate(surf, updateRegion);
|
||||
mTexImage->DirectUpdate(surf.Get(), updateRegion);
|
||||
} else {
|
||||
const YUVImage& yuv = aNewFront.get_YUVImage();
|
||||
|
||||
nsRefPtr<gfxASurface> asurfY =
|
||||
ShadowLayerForwarder::OpenDescriptor(yuv.Ydata());
|
||||
nsRefPtr<gfxImageSurface> surfY = asurfY->GetAsImageSurface();
|
||||
nsRefPtr<gfxASurface> asurfU =
|
||||
ShadowLayerForwarder::OpenDescriptor(yuv.Udata());
|
||||
nsRefPtr<gfxImageSurface> surfU = asurfU->GetAsImageSurface();
|
||||
// XXX do we really need to open this?
|
||||
nsRefPtr<gfxASurface> asurfV =
|
||||
ShadowLayerForwarder::OpenDescriptor(yuv.Vdata());
|
||||
nsRefPtr<gfxImageSurface> surfV = asurfV->GetAsImageSurface();
|
||||
AutoOpenSurface asurfY(OPEN_READ_ONLY, yuv.Ydata());
|
||||
AutoOpenSurface asurfU(OPEN_READ_ONLY, yuv.Udata());
|
||||
AutoOpenSurface asurfV(OPEN_READ_ONLY, yuv.Vdata());
|
||||
nsRefPtr<gfxImageSurface> surfY = asurfY.GetAsImage();
|
||||
nsRefPtr<gfxImageSurface> surfU = asurfU.GetAsImage();
|
||||
nsRefPtr<gfxImageSurface> surfV = asurfV.GetAsImage();
|
||||
mPictureRect = yuv.picture();
|
||||
|
||||
gfxIntSize size = surfY->GetSize();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ipc/AutoOpenSurface.h"
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
#include "TiledLayerBuffer.h"
|
||||
|
||||
|
@ -992,7 +993,8 @@ ShadowThebesLayerOGL::EnsureTextureUpdated()
|
|||
if (mRegionPendingUpload.IsEmpty() || !IsSurfaceDescriptorValid(mFrontBufferDescriptor))
|
||||
return;
|
||||
|
||||
mBuffer->DirectUpdate(mFrontBuffer.Buffer(), mRegionPendingUpload);
|
||||
AutoOpenSurface frontSurface(OPEN_READ_ONLY, mFrontBuffer.Buffer());
|
||||
mBuffer->DirectUpdate(frontSurface.Get(), mRegionPendingUpload);
|
||||
mRegionPendingUpload.SetEmpty();
|
||||
}
|
||||
|
||||
|
@ -1045,15 +1047,15 @@ ShadowThebesLayerOGL::EnsureTextureUpdated(nsIntRegion& aRegion)
|
|||
if (updateRegion.IsEmpty())
|
||||
continue;
|
||||
|
||||
AutoOpenSurface surface(OPEN_READ_ONLY, mFrontBuffer.Buffer());
|
||||
nsRefPtr<TextureImage> texImage;
|
||||
if (!gl()->CanUploadSubTextures()) {
|
||||
// When sub-textures are unsupported, TiledTextureImage expands the
|
||||
// boundaries of DirectUpdate to tile boundaries. So that we don't
|
||||
// re-upload texture data, use the tile iteration to monitor how much
|
||||
// of the texture was actually uploaded.
|
||||
gfxASurface* surface = mFrontBuffer.Buffer();
|
||||
gfxIntSize size = surface->GetSize();
|
||||
mBuffer->EnsureTexture(size, surface->GetContentType());
|
||||
gfxIntSize size = surface.Size();
|
||||
mBuffer->EnsureTexture(size, surface.ContentType());
|
||||
texImage = mBuffer->GetTextureImage().get();
|
||||
if (texImage->GetTileCount() > 1)
|
||||
texImage->SetIterationCallback(EnsureTextureUpdatedCallback, (void *)&updateRegion);
|
||||
|
@ -1062,7 +1064,7 @@ ShadowThebesLayerOGL::EnsureTextureUpdated(nsIntRegion& aRegion)
|
|||
}
|
||||
|
||||
// Upload this quadrant of the region.
|
||||
mBuffer->DirectUpdate(mFrontBuffer.Buffer(), updateRegion);
|
||||
mBuffer->DirectUpdate(surface.Get(), updateRegion);
|
||||
|
||||
if (!gl()->CanUploadSubTextures())
|
||||
texImage->SetIterationCallback(nsnull, nsnull);
|
||||
|
@ -1102,8 +1104,9 @@ ShadowThebesLayerOGL::ProgressiveUpload()
|
|||
|
||||
// Set a tile iteration callback so we can cancel the upload after a tile
|
||||
// has been uploaded and subtract it from mRegionPendingUpload
|
||||
mBuffer->EnsureTexture(mFrontBuffer.Buffer()->GetSize(),
|
||||
mFrontBuffer.Buffer()->GetContentType());
|
||||
AutoOpenSurface frontSurface(OPEN_READ_ONLY, mFrontBuffer.Buffer());
|
||||
mBuffer->EnsureTexture(frontSurface.Size(),
|
||||
frontSurface.ContentType());
|
||||
nsRefPtr<gl::TextureImage> tiledImage = mBuffer->GetTextureImage().get();
|
||||
if (tiledImage->GetTileCount() > 1)
|
||||
tiledImage->SetIterationCallback(ProgressiveUploadCallback, (void *)&mRegionPendingUpload);
|
||||
|
@ -1111,7 +1114,7 @@ ShadowThebesLayerOGL::ProgressiveUpload()
|
|||
mRegionPendingUpload.SetEmpty();
|
||||
|
||||
// Upload a tile
|
||||
mBuffer->DirectUpdate(mFrontBuffer.Buffer(), mRegionPendingUpload);
|
||||
mBuffer->DirectUpdate(frontSurface.Get(), mRegionPendingUpload);
|
||||
|
||||
// Remove the iteration callback
|
||||
tiledImage->SetIterationCallback(nsnull, nsnull);
|
||||
|
@ -1135,13 +1138,11 @@ ShadowThebesLayerOGL::Swap(const ThebesBuffer& aNewFront,
|
|||
{
|
||||
// The double-buffer path is copied and adapted from BasicLayers.cpp
|
||||
if (ShouldDoubleBuffer()) {
|
||||
nsRefPtr<gfxASurface> newFrontBuffer =
|
||||
ShadowLayerForwarder::OpenDescriptor(aNewFront.buffer());
|
||||
AutoOpenSurface newFrontBuffer(OPEN_READ_ONLY, aNewFront.buffer());
|
||||
|
||||
if (IsSurfaceDescriptorValid(mFrontBufferDescriptor)) {
|
||||
nsRefPtr<gfxASurface> currentFront =
|
||||
ShadowLayerForwarder::OpenDescriptor(mFrontBufferDescriptor);
|
||||
if (currentFront->GetSize() != newFrontBuffer->GetSize()) {
|
||||
AutoOpenSurface currentFront(OPEN_READ_ONLY, mFrontBufferDescriptor);
|
||||
if (currentFront.Size() != newFrontBuffer.Size()) {
|
||||
// Current front buffer is obsolete
|
||||
DestroyFrontBuffer();
|
||||
}
|
||||
|
@ -1159,12 +1160,12 @@ ShadowThebesLayerOGL::Swap(const ThebesBuffer& aNewFront,
|
|||
// They might overlap with our old pixels.
|
||||
aNewBackValidRegion->Sub(mOldValidRegion, aUpdatedRegion);
|
||||
|
||||
nsRefPtr<gfxASurface> unused;
|
||||
SurfaceDescriptor unused;
|
||||
nsIntRect backRect;
|
||||
nsIntPoint backRotation;
|
||||
mFrontBuffer.Swap(
|
||||
newFrontBuffer, aNewFront.rect(), aNewFront.rotation(),
|
||||
getter_AddRefs(unused), &backRect, &backRotation);
|
||||
aNewFront.buffer(), aNewFront.rect(), aNewFront.rotation(),
|
||||
&unused, &backRect, &backRotation);
|
||||
|
||||
if (aNewBack->type() != OptionalThebesBuffer::Tnull_t) {
|
||||
aNewBack->get_ThebesBuffer().rect() = backRect;
|
||||
|
@ -1178,12 +1179,13 @@ ShadowThebesLayerOGL::Swap(const ThebesBuffer& aNewFront,
|
|||
if (!mBuffer) {
|
||||
mBuffer = new ShadowBufferOGL(this);
|
||||
}
|
||||
nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(mFrontBufferDescriptor);
|
||||
mBuffer->Upload(surf, aUpdatedRegion, aNewFront.rect(), aNewFront.rotation(), true, mRegionPendingUpload);
|
||||
AutoOpenSurface frontSurface(OPEN_READ_ONLY, mFrontBufferDescriptor);
|
||||
mBuffer->Upload(frontSurface.Get(), aUpdatedRegion, aNewFront.rect(), aNewFront.rotation(), true, mRegionPendingUpload);
|
||||
|
||||
// Schedule a task to progressively upload the texture
|
||||
if (!mUploadTask) {
|
||||
mUploadTask = NewRunnableMethod(this, &ShadowThebesLayerOGL::ProgressiveUpload);
|
||||
// XXX magic delay constant
|
||||
MessageLoop::current()->PostDelayedTask(FROM_HERE, mUploadTask, 5);
|
||||
}
|
||||
}
|
||||
|
@ -1199,8 +1201,8 @@ ShadowThebesLayerOGL::Swap(const ThebesBuffer& aNewFront,
|
|||
if (!mBuffer) {
|
||||
mBuffer = new ShadowBufferOGL(this);
|
||||
}
|
||||
nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront.buffer());
|
||||
mBuffer->Upload(surf, aUpdatedRegion, aNewFront.rect(), aNewFront.rotation(), false, mRegionPendingUpload);
|
||||
AutoOpenSurface frontSurface(OPEN_READ_ONLY, aNewFront.buffer());
|
||||
mBuffer->Upload(frontSurface.Get(), aUpdatedRegion, aNewFront.rect(), aNewFront.rotation(), false, mRegionPendingUpload);
|
||||
}
|
||||
|
||||
*aNewBack = aNewFront;
|
||||
|
|
|
@ -67,19 +67,18 @@ public:
|
|||
MOZ_COUNT_DTOR(ShadowThebesLayerBufferOGL);
|
||||
}
|
||||
|
||||
void Swap(gfxASurface* aNewBuffer,
|
||||
void Swap(const SurfaceDescriptor& aDescriptor,
|
||||
const nsIntRect& aNewRect, const nsIntPoint& aNewRotation,
|
||||
gfxASurface** aOldBuffer,
|
||||
SurfaceDescriptor* aOldDescriptor,
|
||||
nsIntRect* aOldRect, nsIntPoint* aOldRotation)
|
||||
{
|
||||
*aOldDescriptor = mBuffer;
|
||||
*aOldRect = mBufferRect;
|
||||
*aOldRotation = mBufferRotation;
|
||||
nsRefPtr<gfxASurface> oldBuffer = mBuffer;
|
||||
|
||||
mBuffer = aDescriptor;
|
||||
mBufferRect = aNewRect;
|
||||
mBufferRotation = aNewRotation;
|
||||
mBuffer = aNewBuffer;
|
||||
oldBuffer.forget(aOldBuffer);
|
||||
}
|
||||
|
||||
nsIntRect Rect() {
|
||||
|
@ -90,7 +89,7 @@ public:
|
|||
return mBufferRotation;
|
||||
}
|
||||
|
||||
gfxASurface* Buffer() {
|
||||
SurfaceDescriptor Buffer() {
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
|
@ -100,12 +99,11 @@ public:
|
|||
*/
|
||||
void Clear()
|
||||
{
|
||||
mBuffer = nsnull;
|
||||
mBufferRect.SetEmpty();
|
||||
}
|
||||
|
||||
protected:
|
||||
nsRefPtr<gfxASurface> mBuffer;
|
||||
SurfaceDescriptor mBuffer;
|
||||
nsIntRect mBufferRect;
|
||||
nsIntPoint mBufferRotation;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче