Backed out changeset 82747d694e7a (bug 716859) for android reftest-2 timeouts

This commit is contained in:
Ed Morley
2013-02-21 19:54:25 +00:00
parent 248f8a000b
commit 3077eb4cca
52 changed files with 2669 additions and 6041 deletions

View File

@@ -9,9 +9,6 @@
#include "gfxUtils.h"
#include "gfxPlatform.h"
#include "mozilla/Preferences.h"
#include "SurfaceStream.h"
#include "SharedSurfaceGL.h"
#include "SharedSurfaceEGL.h"
#include "BasicLayersImpl.h"
#include "nsXULAppAPI.h"
@@ -59,10 +56,12 @@ protected:
void UpdateSurface(gfxASurface* aDestSurface = nullptr, Layer* aMaskLayer = nullptr);
nsRefPtr<gfxASurface> mSurface;
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
nsRefPtr<mozilla::gl::GLContext> mGLContext;
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
uint32_t mCanvasFramebuffer;
bool mIsGLAlphaPremult;
bool mGLBufferIsPremultiplied;
bool mNeedsYFlip;
bool mForceReadback;
@@ -99,16 +98,15 @@ BasicCanvasLayer::Initialize(const Data& aData)
if (aData.mSurface) {
mSurface = aData.mSurface;
NS_ASSERTION(!aData.mGLContext, "CanvasLayer can't have both surface and GLContext");
NS_ASSERTION(aData.mGLContext == nullptr,
"CanvasLayer can't have both surface and GLContext");
mNeedsYFlip = false;
} else if (aData.mGLContext) {
NS_ASSERTION(aData.mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
mGLContext = aData.mGLContext;
mIsGLAlphaPremult = aData.mIsGLAlphaPremult;
mGLBufferIsPremultiplied = aData.mGLBufferIsPremultiplied;
mCanvasFramebuffer = mGLContext->GetOffscreenFBO();
mNeedsYFlip = true;
MOZ_ASSERT(mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
// [Basic Layers, non-OMTC] WebGL layer init.
// `GLScreenBuffer::Morph`ing is only needed in BasicShadowableCanvasLayer.
} else if (aData.mDrawTarget) {
mDrawTarget = aData.mDrawTarget;
mSurface = gfxPlatform::GetPlatform()->CreateThebesSurfaceAliasForDrawTarget_hack(mDrawTarget);
@@ -148,84 +146,69 @@ BasicCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer)
if (mGLContext) {
if (aDestSurface && aDestSurface->GetType() != gfxASurface::SurfaceTypeImage) {
MOZ_ASSERT(false, "Destination surface must be ImageSurface type.");
NS_ASSERTION(aDestSurface->GetType() == gfxASurface::SurfaceTypeImage,
"Destination surface must be ImageSurface type");
return;
}
// We need to read from the GLContext
mGLContext->MakeCurrent();
gfxIntSize readSize(mBounds.width, mBounds.height);
gfxImageFormat format = (GetContentFlags() & CONTENT_OPAQUE)
? gfxASurface::ImageFormatRGB24
: gfxASurface::ImageFormatARGB32;
nsRefPtr<gfxImageSurface> readSurf;
nsRefPtr<gfxImageSurface> resultSurf;
SharedSurface* sharedSurf = mGLContext->RequestFrame();
if (!sharedSurf) {
NS_WARNING("Null frame received.");
return;
}
gfxIntSize readSize(sharedSurf->Size());
gfxImageFormat format = (GetContentFlags() & CONTENT_OPAQUE)
? gfxASurface::ImageFormatRGB24
: gfxASurface::ImageFormatARGB32;
bool usingTempSurface = false;
if (aDestSurface) {
resultSurf = static_cast<gfxImageSurface*>(aDestSurface);
if (resultSurf->GetSize() != readSize ||
resultSurf->Stride() != resultSurf->Width() * 4)
{
readSurf = GetTempSurface(readSize, format);
usingTempSurface = true;
}
} else {
resultSurf = GetTempSurface(readSize, format);
usingTempSurface = true;
}
MOZ_ASSERT(resultSurf);
if (resultSurf->CairoStatus() != 0) {
MOZ_ASSERT(false, "Bad resultSurf->CairoStatus().");
if (!usingTempSurface)
DiscardTempSurface();
if (!readSurf)
readSurf = resultSurf;
if (!resultSurf || resultSurf->CairoStatus() != 0)
return;
}
MOZ_ASSERT(sharedSurf->APIType() == APITypeT::OpenGL);
SharedSurface_GL* surfGL = SharedSurface_GL::Cast(sharedSurf);
if (surfGL->Type() == SharedSurfaceType::Basic) {
SharedSurface_Basic* sharedSurf_Basic = SharedSurface_Basic::Cast(surfGL);
readSurf = sharedSurf_Basic->GetData();
} else {
if (resultSurf->Format() == format &&
resultSurf->GetSize() == readSize)
{
readSurf = resultSurf;
} else {
readSurf = GetTempSurface(readSize, format);
}
// Readback handles Flush/MarkDirty.
mGLContext->Screen()->Readback(surfGL, readSurf);
}
MOZ_ASSERT(readSurf);
MOZ_ASSERT(readSurf->Stride() == mBounds.width * 4, "gfxImageSurface stride isn't what we expect!");
bool needsPremult = surfGL->HasAlpha() && !mIsGLAlphaPremult;
if (needsPremult) {
gfxImageSurface* sizedReadSurf = nullptr;
if (readSurf->Format() == resultSurf->Format() &&
readSurf->GetSize() == resultSurf->GetSize())
{
sizedReadSurf = readSurf;
} else {
readSurf->Flush();
nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf);
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->SetSource(readSurf);
ctx->Paint();
// We need to Flush() the surface before modifying it outside of cairo.
readSurf->Flush();
mGLContext->ReadScreenIntoImageSurface(readSurf);
readSurf->MarkDirty();
sizedReadSurf = resultSurf;
}
MOZ_ASSERT(sizedReadSurf);
// If the underlying GLContext doesn't have a framebuffer into which
// premultiplied values were written, we have to do this ourselves here.
// Note that this is a WebGL attribute; GL itself has no knowledge of
// premultiplied or unpremultiplied alpha.
if (!mGLBufferIsPremultiplied)
gfxUtils::PremultiplyImageSurface(readSurf);
if (readSurf != resultSurf) {
MOZ_ASSERT(resultSurf->Width() >= readSurf->Width());
MOZ_ASSERT(resultSurf->Height() >= readSurf->Height());
readSurf->Flush();
resultSurf->Flush();
gfxUtils::PremultiplyImageSurface(readSurf, resultSurf);
resultSurf->CopyFrom(readSurf);
resultSurf->MarkDirty();
} else if (resultSurf != readSurf) {
// Didn't need premult, but we do need to blit to resultSurf
readSurf->Flush();
nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf);
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->SetSource(readSurf);
ctx->Paint();
}
// stick our surface into mSurface, so that the Paint() path is the same
@@ -240,11 +223,8 @@ BasicCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
{
if (IsHidden())
return;
FirePreTransactionCallback();
UpdateSurface();
FireDidTransactionCallback();
PaintWithOpacity(aContext, GetEffectiveOpacity(), aMaskLayer);
}
@@ -345,14 +325,28 @@ public:
void DestroyBackBuffer()
{
MOZ_ASSERT(mBackBuffer.type() != SurfaceDescriptor::TSharedTextureDescriptor);
if (IsSurfaceDescriptorValid(mBackBuffer)) {
if (mBackBuffer.type() == SurfaceDescriptor::TSharedTextureDescriptor) {
SharedTextureDescriptor handle = mBackBuffer.get_SharedTextureDescriptor();
if (mGLContext && handle.handle()) {
mGLContext->ReleaseSharedHandle(handle.shareType(), handle.handle());
mBackBuffer = SurfaceDescriptor();
}
} else if (IsSurfaceDescriptorValid(mBackBuffer)) {
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer);
mBackBuffer = SurfaceDescriptor();
}
}
private:
typedef mozilla::gl::SharedTextureHandle SharedTextureHandle;
typedef mozilla::gl::TextureImage TextureImage;
SharedTextureHandle GetSharedBackBufferHandle()
{
if (mBackBuffer.type() == SurfaceDescriptor::TSharedTextureDescriptor)
return mBackBuffer.get_SharedTextureDescriptor().handle();
return 0;
}
BasicShadowLayerManager* BasicManager()
{
return static_cast<BasicShadowLayerManager*>(mManager);
@@ -369,36 +363,8 @@ BasicShadowableCanvasLayer::Initialize(const Data& aData)
if (!HasShadow())
return;
if (mGLContext) {
GLScreenBuffer* screen = mGLContext->Screen();
SurfaceStreamType streamType =
SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread,
screen->PreserveBuffer());
SurfaceFactory_GL* factory = nullptr;
if (!mForceReadback) {
if (BasicManager()->GetParentBackendType() == mozilla::layers::LAYERS_OPENGL) {
if (mGLContext->GetEGLContext()) {
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
if (!isCrossProcess) {
// [Basic/OGL Layers, OMTC] WebGL layer init.
factory = SurfaceFactory_EGLImage::Create(mGLContext, screen->Caps());
} else {
// [Basic/OGL Layers, OOPC] WebGL layer init. (Out Of Process Compositing)
// Fall back to readback.
}
} else {
// [Basic Layers, OMTC] WebGL layer init.
// Well, this *should* work...
factory = new SurfaceFactory_GLTexture(mGLContext, mGLContext, screen->Caps());
}
}
}
if (factory) {
screen->Morph(factory, streamType);
}
}
// XXX won't get here currently; need to figure out what to do on
// canvas resizes
if (IsSurfaceDescriptorValid(mBackBuffer)) {
AutoOpenSurface backSurface(OPEN_READ_ONLY, mBackBuffer);
@@ -423,17 +389,24 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
!mForceReadback &&
BasicManager()->GetParentBackendType() == mozilla::layers::LAYERS_OPENGL)
{
bool isCrossProcess = XRE_GetProcessType() != GeckoProcessType_Default;
// Todo: If isCrossProcess (OMPC), spin off mini-thread to RequestFrame
// and forward Gralloc handle. Signal WaitSync complete with XPC mutex?
if (!isCrossProcess) {
FirePreTransactionCallback();
GLScreenBuffer* screen = mGLContext->Screen();
SurfaceStreamHandle handle = screen->Stream()->GetShareHandle();
GLContext::SharedTextureShareType shareType;
// if process type is default, then it is single-process (non-e10s)
if (XRE_GetProcessType() == GeckoProcessType_Default)
shareType = GLContext::SameProcess;
else
shareType = GLContext::CrossProcess;
mBackBuffer = SurfaceStreamDescriptor(handle, false);
// Call Painted() to reset our dirty 'bit'.
SharedTextureHandle handle = GetSharedBackBufferHandle();
if (!handle) {
handle = mGLContext->CreateSharedHandle(shareType);
if (handle) {
mBackBuffer = SharedTextureDescriptor(shareType, handle, mBounds.Size(), false);
}
}
if (handle) {
mGLContext->MakeCurrent();
mGLContext->UpdateSharedHandle(shareType, handle);
// call Painted() to reset our dirty 'bit'
Painted();
FireDidTransactionCallback();
BasicManager()->PaintedCanvas(BasicManager()->Hold(this),
@@ -466,7 +439,6 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
static_cast<BasicImplData*>(aMaskLayer->ImplData())
->Paint(aContext, nullptr);
}
FirePreTransactionCallback();
UpdateSurface(autoBackSurface.Get(), nullptr);
FireDidTransactionCallback();