Bug 721489 - Allocate a PoT Shmem for the Adreno. This replaces segfaults by visual artifacts

--HG--
extra : rebase_source : 400e392843cf2d15b941e7e94b736106e6b447e2
This commit is contained in:
Benoit Girard 2012-02-09 17:52:03 -05:00
parent c1890c2bfc
commit f778b545b3
11 changed files with 94 additions and 7 deletions

View File

@ -603,6 +603,12 @@ GLContext::IsExtensionSupported(const char *extension)
return ListHasExtension(fGetString(LOCAL_GL_EXTENSIONS), extension);
}
bool
GLContext::PreferPowerOfTwoTextures()
{
return Renderer() == RendererAdreno200;
}
bool
GLContext::CanUploadSubTextures()
{

View File

@ -704,6 +704,12 @@ public:
bool CanUploadSubTextures();
// Quirks mode to force the platform to use Power of Two.
// Currently provided only as a best effort. We're not in a
// state where we can yet quarante that the platform will honor
// this.
bool PreferPowerOfTwoTextures();
/**
* If this context wraps a double-buffered target, swap the back
* and front buffers. It should be assumed that after a swap, the

View File

@ -74,6 +74,14 @@ struct OpCreateImageLayer { PLayer layer; };
struct OpCreateColorLayer { PLayer layer; };
struct OpCreateCanvasLayer { PLayer layer; };
struct LayerForwarderQuirks {
// 1 << 0 -> Use power of two Shmem for GPU that require it.
// The other alternative would be to memcpy the Shmem
// into a PoT buffer before the upload and wasting bandwidth.
// 1 << 1 -> Unused
uint32_t quirks;
};
struct SurfaceDescriptorD3D10 {
WindowsHandle handle;
};
@ -232,6 +240,11 @@ sync protocol PLayers {
parent:
async PLayer();
// LayersBackend can request the quirks from the layer
// fowarder.
sync GetForwarderQuirks()
returns (LayerForwarderQuirks Quirks);
sync Update(Edit[] cset)
returns (EditReply[] reply);

View File

@ -392,7 +392,7 @@ ShadowLayerForwarder::AllocBuffer(const gfxIntSize& aSize,
SharedMemory::SharedMemoryType shmemType = OptimalShmemType();
nsRefPtr<gfxSharedImageSurface> back =
gfxSharedImageSurface::CreateUnsafe(mShadowManager, aSize, format, shmemType);
gfxSharedImageSurface::CreateUnsafe(mShadowManager, aSize, format, shmemType, mUsePoTShmem);
if (!back)
return false;
@ -507,6 +507,11 @@ ShadowLayerForwarder::ConstructShadowFor(ShadowableLayer* aLayer)
return mShadowManager->SendPLayerConstructor(new ShadowLayerChild(aLayer));
}
LayerForwarderQuirks
ShadowLayerManager::GetForwarderQuirks()
{
return LayerForwarderQuirks(0);
}
void
ShadowLayerManager::DestroySharedSurface(gfxSharedImageSurface* aSurface,
@ -583,5 +588,11 @@ IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface)
return SurfaceDescriptor::T__None != aSurface.type();
}
void
ShadowLayerForwarder::SetForwarderQuirks(LayerForwarderQuirks aQuirks)
{
mUsePoTShmem = aQuirks.quirks() & (1 << 0);
}
} // namespace layers
} // namespace mozilla

View File

@ -42,7 +42,8 @@
#define mozilla_layers_ShadowLayers_h 1
#include "gfxASurface.h"
#include "ShadowLayers.h"
#include "ShadowLayersManager.h"
#include "ImageLayers.h"
#include "Layers.h"
@ -51,6 +52,7 @@ class gfxSharedImageSurface;
namespace mozilla {
namespace layers {
class LayerForwarderQuirks;
class Edit;
class EditReply;
class OptionalThebesBuffer;
@ -308,6 +310,8 @@ public:
*/
bool ShouldDoubleBuffer() { return GetParentBackendType() == LayerManager::LAYERS_BASIC; }
void SetForwarderQuirks(LayerForwarderQuirks aQuirks);
protected:
ShadowLayerForwarder();
@ -332,6 +336,7 @@ private:
Transaction* mTxn;
LayersBackend mParentBackend;
bool mUsePoTShmem;
};
@ -359,6 +364,8 @@ public:
/** CONSTRUCTION PHASE ONLY */
virtual already_AddRefed<ShadowCanvasLayer> CreateShadowCanvasLayer() = 0;
virtual LayerForwarderQuirks GetForwarderQuirks();
static void PlatformSyncBeforeReplyUpdate();
protected:

View File

@ -388,6 +388,12 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
return true;
}
bool
ShadowLayersParent::RecvGetForwarderQuirks(mozilla::layers::LayerForwarderQuirks* aQuirks) {
*aQuirks = layer_manager()->GetForwarderQuirks();
return true;
}
PLayerParent*
ShadowLayersParent::AllocPLayer()
{

View File

@ -80,6 +80,8 @@ protected:
NS_OVERRIDE virtual bool RecvUpdate(const EditArray& cset,
EditReplyArray* reply);
NS_OVERRIDE virtual bool RecvGetForwarderQuirks(mozilla::layers::LayerForwarderQuirks* aQuirks);
NS_OVERRIDE virtual PLayerParent* AllocPLayer();
NS_OVERRIDE virtual bool DeallocPLayer(PLayerParent* actor);

View File

@ -935,6 +935,17 @@ LayerManagerOGL::WorldTransformRect(nsIntRect& aRect)
aRect.SetRect(grect.X(), grect.Y(), grect.Width(), grect.Height());
}
LayerForwarderQuirks
LayerManagerOGL::GetForwarderQuirks()
{
uint16_t quirks = 0;
if (mGLContext->PreferPowerOfTwoTextures()) {
quirks |= 1 << 0;
}
return LayerForwarderQuirks(quirks);
}
void
LayerManagerOGL::SetupPipeline(int aWidth, int aHeight, WorldTransforPolicy aTransformPolicy)
{

View File

@ -400,6 +400,8 @@ public:
gfxMatrix& GetWorldTransform(void);
void WorldTransformRect(nsIntRect& aRect);
LayerForwarderQuirks GetForwarderQuirks();
private:
/** Widget associated with this layer manager */
nsIWidget *mWidget;

View File

@ -85,9 +85,11 @@ public:
CreateUnsafe(ShmemAllocator* aAllocator,
const gfxIntSize& aSize,
gfxImageFormat aFormat,
SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC,
bool aUsePoTSharedSurface = false)
{
return Create<ShmemAllocator, true>(aAllocator, aSize, aFormat, aShmType);
return Create<ShmemAllocator, true>(aAllocator, aSize, aFormat,
aShmType, aUsePoTSharedSurface);
}
Shmem& GetShmem() { return mShmem; }
@ -106,14 +108,30 @@ private:
Create(ShmemAllocator* aAllocator,
const gfxIntSize& aSize,
gfxImageFormat aFormat,
SharedMemory::SharedMemoryType aShmType)
SharedMemory::SharedMemoryType aShmType,
bool aUsePoTSharedSurface = false)
{
if (!CheckSurfaceSize(aSize))
return nsnull;
Shmem shmem;
long stride = ComputeStride(aSize, aFormat);
size_t size = GetAlignedSize(aSize, stride);
long stride;
size_t size;
if (aUsePoTSharedSurface) {
printf_stderr("Buffer PoT\n");
int potW = 1;
while( potW < aSize.width ) potW <<= 1;
int potH = 1;
while( potH < aSize.height ) potH <<= 1;
stride = ComputeStride(gfxIntSize(potW, potH), aFormat);
size = GetAlignedSize(gfxIntSize(potW, potH), stride);
} else {
printf_stderr("Buffer NOT PoT\n");
stride = ComputeStride(aSize, aFormat);
size = GetAlignedSize(aSize, stride);
}
if (!Unsafe) {
if (!aAllocator->AllocShmem(size, aShmType, &shmem))
return nsnull;

View File

@ -40,6 +40,7 @@
#include "mozilla/layers/CompositorChild.h"
#include "mozilla/layers/CompositorParent.h"
#include "mozilla/layers/PLayersChild.h"
#include "nsBaseWidget.h"
#include "nsDeviceContext.h"
#include "nsCOMPtr.h"
@ -857,8 +858,12 @@ void nsBaseWidget::CreateCompositor()
PLayersChild* shadowManager =
mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_OPENGL);
LayerForwarderQuirks forwarderQuirk;
shadowManager->SendGetForwarderQuirks(&forwarderQuirk);
if (shadowManager) {
ShadowLayerForwarder* lf = lm->AsShadowForwarder();
lf->SetForwarderQuirks(forwarderQuirk);
if (!lf) {
delete lm;
mCompositorChild = nsnull;